1

I was trying to overload = operator in linked list in C++ and wrote the below code.

template<class T>
class List {

    public:
        List();
        List (T t_data);
 List& operator=(const List<T> &L);
 private:
        template<class L>
            class Node {

                public:
                    L data;
                    Node *next;
                    Node *prev;
                    Node(T t_data) {
                        data = t_data;
                        next = prev = NULL;
                    }
            };

        Node<T> *head;


};

template<class T>
List&  List<T>::operator=(const List<T> &L) {
    Node<T> *t_head = head;
    Node<T> *t_tail = head->prev;
    Node<T> *temp;
    while(t_head ! = t_tail) {
        temp = t_head;
        t_head = t_next;
        delete temp;

    }
    head = L.head;
    t_head = t_tail = temp = NULL;

    return *this;
}

I wrote this code just for practicing templates, pointers and operator overloading, but I want to know the significance of the = operator in this case. As even if I use it like

List L1(2);
List L2(3);
L1 = L2;

Now any changes reflected in L1 will be reflected in L2, so instead of that we can do

List L1(2);
List *L2 = &L1;

This will also solve the above purpose. So why is the = operator of linked lists overloaded in many articles and books?

Edit: @T.C. In reference to your note, if I will not declare Node as a template , the code will be like this

class List {
public:
    List();
    List (T t_data);
    List& operator=(const List<T> &L);
private:
    class Node {
    public:
        T data;
        Node *next;
        Node *prev;
        Node(T t_data) {
            data = t_data;
            next = prev = NULL;
        }
    };
    Node *head;
};

Now if I declare an object of Node in a member function like below

void List::func() {
    Node temp;
    …..
}

Then how can it be resolved that what is the type of data member “data” of this “temp” object is. Please let me know.

T.C.
  • 133,968
  • 17
  • 288
  • 421
Learner
  • 59
  • 8
  • 3
    What is the question? – Frerich Raabe Jun 17 '14 at 06:57
  • 3
    It is up to you to decide what semantics assignment should have, but it is quite idiomatic in C++ to use value semantics, i.e. `L1` would *not* be sharing the same data as `L2` but it would be a copy, owning all of its nodes. Because, as you pointed out, the language gives you the means to use reference semantics via references or pointers. – juanchopanza Jun 17 '14 at 06:57
  • Two `List` instances sharing the same `head` after assignment looks wrong for me! Related: http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – πάντα ῥεῖ Jun 17 '14 at 06:59
  • But on top of what I said before, I think you need to clarify your question. Or, if it covers too many issues, split it into smaller ones. – juanchopanza Jun 17 '14 at 07:05
  • I assume that "why in many articles and books = operator is overloaded in linked list." is actually the question... – T.C. Jun 17 '14 at 07:09
  • `t_next` is undeclared in your `operator=` – M.M Jun 17 '14 at 07:52
  • 1
    See also: [the copy and swap idiom](http://stackoverflow.com/q/3279543/430766). – bitmask Jun 17 '14 at 07:56

1 Answers1

5

In C++, the usual practice is to have value semantics, i.e., after L1 = L2;, changes to L1 would not be visible in L2, and vice versa.

Thus your implementation of operator = is wrong. What it should do is:

  1. Make a copy of the nodes stored in the other linked list.
  2. Destroy all nodes stored in the current linked list
  3. Store the copy made in step 1 into the current linked list

A common idiom is the copy and swap idiom: You create a temporary copy of the other linked list (point 1), swap the contents of the current linked list with the temporary copy (point 3), and when your assignment function returns, the temporary copy is destroyed along with the former contents of the linked list assigned to (point 2).

Can you do it differently? Sure, but it (1) is very unidiomatic and (2) requires far more than what you have now to do correctly. For example, your current implementation of operator = will cause double deletion when L1 and L2's destructors run after an assignment. You'd need some sort of reference counting and additional logic in the destructor to ensure that you don't delete a Node that's still being used, but also do not leak memory.

Side note: Node should not be a template since it should never store something other than a T.

Community
  • 1
  • 1
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • The (2) point you mentioned is exactly what I did in the while loop of the = overloader. Further I dint get how in my logic deletion is done twice..could you please let me know – Learner Jun 17 '14 at 07:23
  • @Learner Your `operator =` needs to do all three points, not just one. Note that the `List` destructor must `delete` all the nodes it owns, or it will leak memory. Consider what happens after `L1 = L2;` when the destructors of `L1` and `L2` run. (Or, consider a destructor-less example: what happens when you do `L1 = L2; L1 = L3; L2 = L3;`?) – T.C. Jun 17 '14 at 07:28
  • @Learner imagine if your `operator=` made two `List` objects that both contain the exact same nodes. You destroy one `List`; that destructor destroys all the nodes it contains. Now the other `List` still exists but all its pointers point to objects that have been deleted, so you will be in trouble as soon as you do any operation on the other `List`. – M.M Jun 17 '14 at 07:54
  • it may be worth mentioning the [copy and swap idiom](http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap) – risingDarkness Jun 17 '14 at 07:54
  • @T.C. please look into the below answer section where I have asked further query of the question – Learner Jun 17 '14 at 10:09
  • @Learner `List` is still a template, and different `List::Node`s are actually different types and will have different types of its data member. C++ is clever enough for that. – T.C. Jun 17 '14 at 13:59