Как правильно реализовать конструктор и оператор копирования для указателей объектов? - PullRequest
0 голосов
/ 19 января 2020

Я пытаюсь создать конструктор копирования и оператор присваивания для указателей объектов Next и Prev, но я не получаю правильные данные, когда он пытается копировать. Я не уверен, что реализовал это неправильно.

Узел. cpp

Node::Node(const Node& h) 
{
    Next = new Node(*h.Next);
    Prev = new Node(*h.Prev);
    data = h.data;
}

Node::~Node()
{
    delete Next;
    delete Prev;
}
Node& Node::operator=(const Node& t) 

{
    delete Next;
    delete Prev;
    Next = new Node(*t.Next);
    Prev = new Node(*t.Prev);
    data = t.data;
    return *this;

}
Node.H
Private: 
Node* Next;
Node* Prev;
int data;

Ответы [ 2 ]

1 голос
/ 19 января 2020
Node::~Node()
{
    delete Next;
    delete Prev;
}

Пока узел уничтожается, он уничтожает своего преемника. Который в свою очередь уничтожает своего предшественника, который уничтожает его преемника, который уничтожает его предшественника, который уничтожает ... Можете ли вы определить проблему? Эта рекурсия бесконечна. Это никогда не заканчивается. Кроме того, поведение не определено, поскольку вы удаляете значение указателя, которое уже удаляется. Как правило, перечислять операции go можно только одним способом. Вам не нужно go возвращаться назад, потому что именно отсюда «взялся» алгоритм.

Даже если мы исправим проблему, не идя в обоих направлениях, другая проблема с рекурсией заключается в том, что она настолько глубока как длина списка. Учитывая, что большинство систем обычно имеют ограниченный размер стека вызовов, это накладывает неявное ограничение на максимальный размер списка. Как правило, операции со связанным списком должны использовать итерацию, а не рекурсию.

Обе проблемы возникают во всех показанных функциях.

Я не пытаюсь выполнить глубокое копирование в классе.

Тогда вы допустили ошибку, так как ваш конструктор копирования и оператор присваивания выполняют глубокое копирование - или, по крайней мере, они выглядят как испорченные версии глубокого копирования.

Если вы хотите поверхностное копирование, тогда вы хотите, что делают неявно сгенерированные операции. И если вы хотите мелкое копирование, то вам также следует хотеть, чтобы указатели не были собственниками, и поэтому хотели бы также использовать неявный деструктор.

1 голос
/ 19 января 2020

У вас не должно быть конструктора копирования для Node. Делать копию узла не имеет смысла.

Узел является элементом списка. Должна ли копия быть дублирующим узлом в этом же списке? Но где в списке? Во главе? В конце? С начала? Это не имеет смысла.

Сделать копию должен быть дублирующим узлом в другом списке? Но в каком списке? Опять же, это не имеет смысла.

Почему, по вашему мнению, у вашего Node класса должен быть конструктор копирования? Как вы думаете, что он должен делать?

Если у вас есть ответ на этот вопрос, то создайте конструктор копирования. Если вы этого не сделаете, не .

Тот же лог c относится к оператору присваивания. Что это должно сделать? Там нет очевидного ответа. Поэтому, если у вас нет точного представления о том, что он должен делать, не пишите .

...