您的位置:首页 > 其它

拷贝构造函数的形参应是类对象的引用,而不是对象的值

2010-03-22 19:42 204 查看
有一个抽象类,如下:

class NoName {

public:

      NoName(): pstring(new string), i(0), d(0.0) {}

      NoName(const Noname &noName): pstring(new string(*noName.pstring)), i(noName.i), d(noName.d) {}

private:

      string *pstring;

      int i;

      double d;

};

 

拷贝构造函数也是构造函数,有一个形参,是对本类类型对象的引用。拷贝构造函数有四个方面的作用:

1)利用已有对象显式或隐式初始化一个新对象;

2)复制一个对象,将它作为实参传给一个函数;

3)从函数返回时复制一个对象;

4)初始化顺序容器中的元素

5)显式初始化(利用数组的初始化列表)数组元素。

 

从拷贝构造函数的定义可以看出,这种构造函数的形参是对本类对象的引用。假设有下面的情况:

NoName nn1;                // 定义一个NoName类类型的对象nn1,并隐式调用默认构造函数初始化这个对象

NoName nn2(nn1);      // 将nn1对象的值拷贝给nn2

 

对象之间的赋值,会调用拷贝构造函数。如果拷贝构造函数的形参不是对象的引用,而是对象本身,在调用拷贝构造函数的时候会发生什么?

如果拷贝构造函数的形参是对象本身,即定义NoName(const NoName nn),在调用它的时候,由于是值传递,主调函数(NoName nn2(nn1); 会调用拷贝构造函数)会把实参的副本传递给形参。那么实参的副本怎么来的(实参是对象)?当然也是调用拷贝构造函数生成的。但是调用拷贝构造函数生成副本的过程中,又会调用拷贝构造函数,这样,拷贝构造函数就会一直递归调用,直到耗尽栈空间程序崩溃。

因此,答案是:如果拷贝构造函数的形参是对象本身,它就会一直被递归调用,直到耗尽栈空间程序崩溃。

 

因此,拷贝构造函数的形参一定要是对象的引用,因为这样才不会发生值传递。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string class