我正在试验一个链表。我的函数“null”似乎修改了我的列表,即使列表没有通过引用传递。我已经读过这些问题可能发生在作为普通的call-by-value参数传递的对象上,并且它是一个原因,即类中的数据未被声明为良好OOP中的公共成员。我已经尝试将null函数作为列表的成员函数,它工作正常,但我仍然想知道为什么这种方法不能正常工作。 感谢
#include <iostream>
#include <new>
#include <time.h>
#include <stdlib.h>
using namespace std;
class list{
public:
struct element {
int data;
element* next;
};
element * head;
list(){
head=NULL;
}
~list(){
while (head!=NULL){
element *e = head->next;
delete head;
head = e;
}
cout<<"Destructing..\n";
}
void add (int value){
element *e = new element;
e->data = value;
e->next = head;
head= e;
}
};
void fill10 (class list & l){
for (int i= 0; i<10 ;i++){
l.add((rand()%10)+1);
}
}
bool null (class list l){
if (l.head!=NULL){ return false;}
return true;
}
int main ()
{
srand(time(NULL));
class list l;
fill10(l);
cout<<l.head->data<<endl;
cout<<l.head<<endl;
cout<<endl<<null(l)<<endl;//when I comment this everything works out as expected
cout<<l.head->data<<endl; //this data is not the same anymore after null is called
cout<<l.head<<endl;
return 0;
}
答案 0 :(得分:2)
问题在于您将参数传递给null
函数
bool null (class list l){
if (l.head!=NULL){ return false;}
return true;
}
按值传递时,您可以创建链接列表的副本。此副本将包含与原始副本相同的head
指针的副本。
当函数返回时,参数将被销毁,其析构函数将删除原始文件和副本之间共享的所有节点。
您必须通过引用传递,或者定义为复制列表创建新节点的复制构造函数。
答案 1 :(得分:0)
您的null
函数需要list
个值,但list
中的内容是什么?它实际上只是指向实际内容的指针(element
)。因此,当你按值调用时最终被复制的不是东西(element
)而是指向东西的指针。
这就是为什么它有效,就像现在一样。
答案 2 :(得分:0)
当您将l
按值传递给null
时,您会调用复制构造函数,并且该副本的head
将指向与head
相同的l
。当此副本超出null
末尾的范围时,head
将被删除,这与head
使用的l
相同。
C ++中有一种称为“三规则”的东西,它指出无论何时定义析构函数,复制构造函数或赋值,都应该定义所有这些。