Конструктор и константная ссылка

Я сейчас изучаю C ++ (начал как 2 дня назад), и у меня есть некоторые проблемы с написанием Copy C’tor of Node.
Узел является классом следующим образом:

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

Примечание: у меня есть оператор *, так что * фиктивные результаты в T-типе.

Еще одно примечание: мои публичные и приватные поля могут быть неправильными — но я рассмотрю это позже.

После того, как вы немного потрепали, давайте посмотрим на Copy C’tor, пожалуйста.

Он получает постоянную ссылку на Node, а затем я попытался создать указатель на него. Компилятор выдает ошибку:
Node<T>* dummy= &node; Результаты invalid conversion from 'const Node<int>*' to 'Node<int>*' (У меня есть короткая основная попытка создать Node<int>).

Итак, похоже, что я не могу создать указатель на const, поэтому я попытался скопировать его поля вручную, как показано в коде.
Когда я запускаю отладчик Eclipse и проверяю, работает ли он — он работает.
Однако, когда я продолжаю делать шаги, вызывается D’tor голова (в конце конструктора копирования) и в результате все разваливается.
Поэтому я понятия не имею, что делать дальше, или даже если я на правильном пути.

Как мне сделать конструктор копирования? Я думаю, что понимаю, почему вызывается D’Tor (я что-то создал, и в конце блока что-то разрушено — верно?), Но я не знаю, как сделать это правильно.

1

Решение

Цель конструктора копирования — сделать «точную копию» переданного объекта. Так что в зависимости от семантики data а также next указатели, которые вы бы просто присвоили им, используя список инициализаторов:

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

Поскольку это так же, как ожидаемое поведение по умолчанию (члены копирования), вы можете просто опустить конструктор копирования, и компилятор сгенерирует подходящий конструктор по умолчанию.

Обратите внимание, что вы можете определенно создать указатель на const object: на что жалуется компилятор, так это то, что объявление типа для вашего указателя теряет const немного в процессе.

Второе замечание: для глубокой копии вы можете использовать что-то вроде:

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

Конечно, в этом сценарии глубокого копирования ваш контейнер берет на себя «владение» полями-членами (что вызывает вопрос: почему они в первую очередь являются указателями?) И поэтому должен быть осторожен с delete их в деструкторе.

1

Другие решения

Код, который вы разместили, не совсем соответствует заявлению, которое вы цитировали с ошибкой:

Node<T>* dummy= &node;

Но в любом случае, вы можете сделать это:

const Node<T>* dummy= &node;

Так как node является constлюбые ссылки или указатели на него также должны быть const, Вы также не сможете вызывать неконстантные методы на nodeпоэтому любые методы, которые вы используете для методов доступа к данным, должны быть правильными.

0