我建议你从实现析构函数开始List
。由于您通过使用动态分配内存new
,你应该使用释放它delete
。 (如果您使用new[]
, 这将是delete[]
):
~List()
{
Node* currentNode = this->root; // initialize current node to root
while (currentNode)
{
Node* nextNode = currentNode->getNext(); // get next node
delete currentNode; // delete current
currentNode = nextNode; // set current to "old" next
}
}
一旦你有了正确的析构函数,你应该尝试你的复制构造函数是否正确:
List* lala = new List(*l);
delete l; // delete list that was used to create copy, shouldn't affect copy
您会发现您的复制构造函数是错误的,并且还会导致您的应用程序崩溃。为什么?因为目的复制构造函数就是创建一个new对象作为现有对象的副本。你的复制构造函数只是复制指针假设sizeof(Node*)
等于sizeof(int)
。它应该看起来像这样:
List(const List& list)
{
// if empty list is being copied:
if (!list.root)
{
this->root = NULL;
return;
}
// create new root:
this->root = new Node(NULL, list.root->getWrt());
Node* list_currentNode = list.root;
Node* this_currentNode = this->root;
while (list_currentNode->getNext())
{
// create new successor:
Node* newNode = new Node(NULL, list_currentNode->getNext()->getWrt());
this_currentNode->setNext(newNode);
this_currentNode = this_currentNode->getNext();
list_currentNode = list_currentNode->getNext();
}
}
还有你的功能remove
是错误的,因为它“删除”了对某个节点的引用,但从未释放该节点所在的内存。delete
应该调用以释放该内存。
“我需要在节点上实现工作析构函数”- 不,你不知道。节点本身不分配任何内存,因此它不应该释放任何内存。节点不应该负责销毁Node* next
也不清理存储它的内存。不要实现 Node 的析构函数或复制构造函数。您还想阅读以下内容:什么是三法则? https://stackoverflow.com/q/4172722/1168156
“使列表对 Node 友好,这样我就不必使用 getNext()”- 你想说在 Node 类中,class List
is its friend
:
class Node
{
friend class List; // <-- that's it
请注意,您的代码包含的这 5 个标头中只需要一个:<iostream>
。
还要注意写using namespace std;
在文件的开头被认为是不好的做法因为它可能会导致某些类型的名称变得不明确。在小范围内明智地使用它或使用std::
前缀代替。