1

私は現在 C++ を勉強しています (2 日前のように始めました) が、Node.js のコピー C'tor を書くのに問題があります。ノードは次のようなクラスです:

template <class T>
class Node {
        T* data;
        Node<T>* next;
        friend class Iterator<T>;
    public:
        Node():data(NULL),next(NULL){}
        Node(const T& data):data(NULL),next(NULL){
                T* copy = new T(data);
                this->data = copy;
        }

        Node(const Node& node):data(NULL),next(NULL){

            Node<T> dummy;
            dummy.data = node.data;
            dummy.next = node.next;
            Node<T>* head=new Node(*dummy);
            *this = *head;
            while(dummy.next != NULL) {
                dummy = *(dummy.next);
                head = head->next;
                head = new Node(*dummy);
            }
        }

注: 私は operator* を持っているので、 *dummy は T 型になります。

別の注意: 私の公開フィールドと非公開フィールドは間違っている可能性がありますが、後で対処します。

少し吐いたら、コピー C'tor を見てみましょう。

ノードの const 参照を取得し、それへのポインターを作成しようとしました。コンパイラはエラーを出力します: Node<T>* dummy= &node;results invalid conversion from 'const Node<int>*' to 'Node<int>*'(作成しようとしている短いメインがありますNode<int>)。

わかりましたので、constへのポインタを作成できないようですので、コードに示されているようにフィールドを手動でコピーしようとしました。Eclipse デバッガーを実行して動作するかどうかを確認すると、動作します。ただし、ステップを作成し続けると、D'tor が先頭で (コピー コンストラクターの最後で) 呼び出され、その結果、すべてがバラバラになります。そのため、次に何をすべきか、あるいは自分のやり方が正しいかどうかさえわかりません。

コピー コンストラクターはどのように作成すればよいですか? D'tor が呼び出される理由は理解できたと思います (私は何かを作成し、ブロックの最後で何かが破壊されました - ですよね?) が、それを正しくする方法がわかりません。

4

2 に答える 2

1

コピー コンストラクターの目的は、渡されたオブジェクトの「正確なコピー」を作成することです。dataしたがって、とポインターのセマンティクスに応じてnext、初期化子リストを使用してそれらを割り当てるだけです。

Node(const Node& node): data(node.data), next(node.next) {}

これは予想される既定の動作 (コピー メンバー) とまったく同じであるため、単純にコピー コンストラクターを省略でき、コンパイラーは既定で適切なコンストラクターを生成します。

オブジェクトへのポインターを間違いなく作成できることに注意してくださいconst。コンパイラーが不平を言っているのは、ポインターの型宣言がconstプロセスでビットを失うことです。

2 番目の注意: ディープ コピーの場合は、次のようなものを使用できます。

Node(const Node& node): 
    data(node.data == NULL? NULL: new T(*node.data)),
    next(node.next == NULL? NULL: new Node(*node.next)) {}

もちろん、そのディープ コピー シナリオでは、コンテナーはメンバー フィールドの「所有権」を取得しているため (そもそもなぜポインターなのかという疑問が生じます) delete、デストラクタでそれらを適切に処理するように注意する必要があります。

于 2015-06-12T00:00:52.373 に答える
0

投稿したコードは、エラーで引用したステートメントと完全には一致しません。

Node<T>* dummy= &node;

とにかく、これを行うことができます:

const Node<T>* dummy= &node;

nodeであるためconst、それへの参照またはポインタも である必要がありますconst。また、で const 以外のメソッドを呼び出すこともできないnodeため、データ アクセサー用に作成するメソッドはすべて const に対応している必要があります。

于 2015-06-12T00:01:40.613 に答える