Constructor and const reference

506 views Asked by At

I;m study C++ right now (started like 2 days ago) and I have some trouble with writing Copy C'tor of Node. Node is a class as following:

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

Note: I have operator* so *dummy results in T type.

Another Note: My public and private fields may be wrong - but I will deal with it later.

After you puked a bit, let's look at the Copy C'tor please.

It gets a const refernce of Node, and then I tried to create a pointer to it. The compiler outputs an error: Node<T>* dummy= &node; results invalid conversion from 'const Node<int>*' to 'Node<int>*' (I have a short main trying to create Node<int>).

Ok, so it seems like I can't create a pointer to a const, so I tried to copy it's fields manualy as shown in code. When I run Eclipse debugger and check if it works - it does. However, when I keep making steps the D'tor is called on head (in the end of the copy constructor) and as a result everything falls apart. So I have no idea what to do next, or even if I am in the right way.

How should I make the copy constructor? I think I understand why the D'tor is called (I created something and in the end of the block, that something is destroyed - right?), but I don't know how to make it right.

2

There are 2 answers

9
user268396 On BEST ANSWER

The purpose of the copy constructor is to make an 'exact copy' of the passed object. So depending on the semantics of data and next pointers you would simply assign them using an initialiser list:

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

Since this is just like expected default behaviour (copy members), you can simply omit the copy constructor and the compiler will generate a suitable one by default.

Note that you can definitely create a pointer to a const object: what the compiler is complaining about is that the type declaration for your pointer loses the const bit in the process.

Second note: for a deep copy you could use something like:

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

Of course, in that deep copy scenario your container is taking "ownership" of the member fields (which prompts the question: why are they pointers in the first place?) and should therefore be careful to properly delete them in a destructor.

3
paddy On

The code you posted doesn't quite match the statement that you quoted with the error:

Node<T>* dummy= &node;

But anyway, you can do this:

const Node<T>* dummy= &node;

Because node is const, any references or pointers to it must also be const. You also won't be able to call non-const methods on node, so any methods you make for data accessors will need to be const-correct.