0

リンクリストを実装しています。私はコピーコンストラクタを書きました:

        // --- copy constructor ---
    IntList(const IntList& last_list) {
        first = new IntNode(last_list.getFirst()->getData());
        cout << "copy first " << first->getData() << endl;

        IntNode* last_node = first;
        IntNode* node = last_list.getFirst()->getNext();
        while(node!=NULL) {
            IntNode* new_node = new IntNode(node->getData());
            last_node->setNext(new_node);
            cout << "copy " << new_node->getData()<< endl;
            last_node = new_node;
            node = node->getNext();
        }
    }

私が理解しているように、コピー代入演算子 ( operator=) には 2 つの目標が必要です。

  • 現在のリストを削除します。
  • 新しいリストをコピーします。

この 2 つの目標は、既に作成したデストラクタを呼び出してからコピー コンストラクタを呼び出すことで達成できます。どうすればいいですか?

4

2 に答える 2

9

コピー代入演算子には、コピー アンド スワップイディオムを使用できます。

たとえば、あなたの場合、これをIntListクラス定義に追加できます(コピーコンストラクターのコードを考えると、唯一のデータメンバーは であると想定していますIntNode* first;):

        // --- swap non-member function ---
    friend void swap(IntList& a, IntList& b) /* no-fail */ {
        // swap data members one by one
        std::swap(a.first, b.first);
    }

        // --- (copy) assignment operator ---
    IntList& operator=(const IntList& other) {
        IntList temp(other); // copy construction
        swap(*this, temp);   // swap
        return *this;
                             // destruction of temp ("old *this")
    }

実際、これはより良いスタイルかもしれません:

        // --- swap non-member function ---
    friend void swap(IntList& a, IntList& b) /* no-fail */ {
        using std::swap; // enable ADL
        // swap data members one by one
        swap(a.first, b.first);
    }

        // --- (copy) assignment operator ---
    IntList& operator=(IntList other) { // note: take by value
        swap(*this, other);
        return *this;
    }

コメントは、C++98/03 ではC++11で(またはコメントだけで)/* no-fail */置き換えることができます。throw()/* throw() */noexcept

(注: C++98/03 では、C++11 ではstd::swap、適切なヘッダーを事前に含めることを忘れないでください(両方を含めることもできます)。)<algorithm><utility>

注意: ここでは、swap関数はクラス本体で定義されていますが、それにもかかわらず、それfriend.

ストーリー全体については、リンクされた投稿を参照してください。

(もちろん、コピー コンストラクターに加えて、正しいデストラクタ定義も提供する必要があります ( What is The Rule of Three? を参照してください)。

于 2013-06-12T20:27:56.307 に答える
1

必要な機能を、デストラクタ、コピー コンストラクタ、および代入演算子によって呼び出される個別の関数に入れます。

于 2013-06-12T20:27:41.463 に答える