返回*这引起了很大的挫败感
我已经使用 C 大约一年了,最后决定学习 C++。我正在尝试像这样实现我自己的链表类:
#include <cstdio>
#include <cstdlib>
struct linked_list_node
{
int value;
struct linked_list_node* next;
};
class LinkedList
{
linked_list_node* head;
public:
LinkedList add(int value)
{
printf("add calledn");
if (head == nullptr)
{
head = new linked_list_node;
head->value = value;
head->next = nullptr;
}
else
{
linked_list_node* curr = head;
while (curr->next != nullptr) curr = curr->next;
curr->next = new linked_list_node;
curr->next->value = value;
curr->next->next = nullptr;
}
return *this;
}
int get(size_t index)
{
linked_list_node* curr = head;
for (int i = 0; i < index; i++) curr = curr->next;
return curr->value;
}
LinkedList()
{
head = nullptr;
}
~LinkedList()
{
linked_list_node* curr = head, * temp;
while (curr != nullptr)
{
temp = curr;
curr = curr->next;
delete temp;
}
}
};
int main()
{
LinkedList l;
l.add(1);
l.add(2);
printf("%dt%dn", l.get(0), l.get(1));
return 0;
}
这会导致发生异常。我发现了错误,这是方法add返回*this. 这导致析构函数在 之后被调用l.add(1),从而删除了对 的分配head并搞砸了整个程序。将add方法定义为:
void add(int value) // void method
{
printf("add calledn");
if (head == nullptr)
{
head = new linked_list_node;
head->value = value;
head->next = nullptr;
}
else
{
linked_list_node* curr = head;
while (curr->next != nullptr) curr = curr->next;
curr->next = new linked_list_node;
curr->next->value = value;
curr->next->next = nullptr;
}
// doesn't return *this
}
代码运行完美。有人可以解释为什么返回*this会导致析构函数被调用。提前致谢 :)
回答
你的add函数返回一个副本的LinkedList。由于您没有提供复制构造函数,因此您使用的是编译器生成的构造函数,它只是逐个元素地复制成员。当您复制指针时,进行双重释放或在指针被释放后尝试使用指针会带来巨大的危险。
有一条准则称为“三规则”(请参阅什么是三规则?),它说如果您有构造函数或析构函数,则可能也需要有复制构造函数。这是为了让你远离这种麻烦。