0

I'm implementing a linked list. I wrote a copy constructor:

        // --- 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();
        }
    }

As I understand, my copy-assignment operator (operator=) should have 2 goals:

  • delete the current list.
  • copy the new list.

I can achieve this 2 goals by calling the destructor which I already wrote and then call the copy constructor. How can I do it?

gx_
  • 4,690
  • 24
  • 31
Shelef
  • 3,707
  • 6
  • 23
  • 28
  • What's an assignment constructor? – chris Jun 12 '13 at 20:26
  • Its copy assignment operator you mean. And AFAIK, you can't define this in terms of the copy constructor. – Mike Vine Jun 12 '13 at 20:28
  • 4
    @MikeVine: sure you can. The common Copy-and-swap for copy assignemtn works via the copy constructor – Mooing Duck Jun 12 '13 at 20:29
  • I see that you have edited your post, but the point of my parenthesis was not to replace "assignment" with "copy-assignment", but to replace "constructor" with "operator"... (Besides, the "copy assignment operator" is often simply called the "assignment operator". The "copy" prefix just adds precision: e.g. for `std::string`, both `string& operator=(const string&)` and `string& operator=(const char*)` are assignment operators, but only the first is a _copy_ assignment operator, because the argument is of the same type as the class. It's a parallel to constructors and _copy_ constructor.) – gx_ Jun 12 '13 at 21:03

2 Answers2

9

For your copy assignment operator, you can use the copy-and-swap idiom.

For example in your case, you could add this into your IntList class definition (given the code of your copy constructor, I'm assuming that your only data member is 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")
    }

Actually, this may be better style:

        // --- 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;
    }

The /* no-fail */ comment can be replaced with throw() (or maybe just a /* throw() */ comment) in C++98/03, noexcept in C++11.

(Note: Don't forget to beforehand include the right header for std::swap, that is, <algorithm> in C++98/03, <utility> in C++11 (you can as well include both).)

Remark: Here the swap function is defined in the class body but it is nevertheless a non-member function because it is a friend.

See the linked post for the whole story.

(Of course, you must also provide a correct destructor definition in addition to your copy constructor (see What is The Rule of Three?).)

Community
  • 1
  • 1
gx_
  • 4,690
  • 24
  • 31
1

Put the functionality you need in separate functions called by the destructor and the copy constructor and the assignment operator.

HeywoodFloyd
  • 166
  • 1
  • 12