为什么要使用对复制构造函数的参数的引用?
我发现很多信息表明,这是为了避免无限制的通话,但我仍然听不懂。
答案 0 :(得分:7)
按值传递给方法时,将复制该参数。复制使用复制构造函数,因此您对复制构造函数进行无限递归调用会遇到麻烦。
回复评论:
通过引用传递不会使对象的副本开始传递。它只是传递对象的地址(隐藏在引用语法之后),因此复制构造函数内部的对象(或通过引用传递对象的任何方法)与外部对象是同一对象。
除了在这里解决“鸡与蛋”问题外,按引用传递通常更快(对于较大的对象-大于一个点的大小)。
回应进一步评论:
您可以编写一种通过指针传递的复制构造函数,并且其工作方式与通过引用传递的方式相同。但是显式地调用是不可能的,而隐式地调用是不可能的。
声明:
class X
{
public:
X();
X(const X* const pOther);
};
显式副本:
X x1;
X x2(&x1); // Have to take address
隐式副本:
void foo (X copyOfX); // Pass by value, copy made
...
X x1;
foo (x1); // Copy constructor called implicitly if correctly declared
// But not matched if declared with pointer
foo (&x1); // Copy construcxtor with pointer might (?) be matched
// But function call to foo isn't
最终,这样的事情将不被视为C ++复制构造函数。
答案 1 :(得分:5)
此代码:
class MyClass {
public:
MyClass();
MyClass(MyClass c);
};
不编译。也就是说,因为第二行在这里:
MyClass a;
MyClass b(a);
理论上应该引起您正在讨论的无限循环-在调用a
的构造函数之前,它应该构造b
的副本。但是,如果复制构造函数如下所示:
MyClass(const MyClass& c);
然后在调用副本构造函数之前无需复制任何副本。
答案 2 :(得分:1)
从此webpage
按值传递对象时,将调用复制构造函数。复制 构造函数本身就是一个函数。因此,如果我们按值传递参数 在复制构造函数中,将对复制构造函数进行调用 调用副本构造函数,它成为一个非终止的调用链。 因此,编译器不允许按值传递参数。
通过传递参数值,副本构造函数将调用自身,从而进入无限的“递归循环”。上面的链接很好地解释了有关复制构造函数的基本主题。