function修改未引用的类

时间:2012-06-28 12:54:53

标签: c++ class

我正在试验一个链表。我的函数“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;
}

3 个答案:

答案 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 ++中有一种称为“三规则”的东西,它指出无论何时定义析构函数,复制构造函数或赋值,都应该定义所有这些。