我正在尝试创建一个链表,但遇到了问题,因为我要删除两次节点。只有当一个节点被传递给一个函数时才会出现这个问题(如果它通过引用传递一切都很好),这使我相信传递给函数的对象正在以指针指向节点的方式被复制从原始列表而不是新列表。我试图通过重载=运算符来解决这个问题,但这也不起作用。对我做错的解释会很棒。
感谢您的帮助
#include <iostream>
struct node{
node(int n){
if (n == 1){
data = 1;
next = NULL;
}
if (n == 2){
data = 2;
next = new node(1);
next -> next = NULL;
}
}
~node(){
std::cout << data << std::endl;
if (next != NULL) delete next;
}
void operator=(node a){
next = NULL;
}
int data;
node* next;
};
void func2(node v){
}
int main(){
node v(2);
if (v.next -> next == NULL) std::cout << "true\n";
func2(v);
return 0;
}
答案 0 :(得分:3)
你的怀疑是正确的,但其中存在问题;当您将节点传递到func2
时,您只复制第一个节点,而不是整个列表。复制构造函数将复制第一个节点和第一个节点中的指针(指向原始的第二个节点),因此当v
超出func2
中的范围时,它会被删除一次,然后获取当它超出main
的范围时再次删除。您需要编写复制构造函数来执行深层复制,&#34;遍历整个列表并将每个节点复制到一个新地址。
还要记住,在大多数情况下,复制构造函数应该返回*this
,这可以在C ++常见问题解答中和#34; Effective C ++&#34;作者:Scott Meyers。因此签名应该是:
node& operator=(const node& node);
如果您要重载赋值运算符,您可能还应该定义一个复制构造函数。顺便说一句,好解释这个问题。
编辑:代码看起来像这样。我很抱歉我没有测试过这个;我在平板电脑上编辑这个很痛苦......
#include <iostream>
struct node{
node(const node& toCopy) : data(toCopy.data)
{
if(toCopy.next != null) {
next = new node(toCopy);
}
}
node(int n){
if (n == 1){
data = 1;
next = NULL;
}
if (n == 2){
data = 2;
next = new node(1);
next -> next = NULL;
}
}
node& operator=(const node& toCopy) {
if(&toCopy != this) {
data = toCopy.data;
if(next != NULL) {
next = new node(toCopy);
}
}
return *this;
}
~node(){
std::cout << data << std::endl;
if (next != NULL) delete next;
}
int data;
node* next;
};
void func2(node v){
}
int main(){
node v(2);
if (v.next -> next == NULL) std::cout << "true\n";
func2(v);
return 0;
}