我可以显式调用复制构造函数吗?

时间:2010-02-06 17:11:01

标签: c++ copy-constructor

我对复制构造函数的机制有点困惑。如果我错了,请纠正我:

如果一个方法将一个对象的引用作为参数,并且该类定义了一个复制构造器,那么该类使用构造函数来创建自身的副本,并将其传递给函数而不是对原始函数的引用宾语?

此外,可以致电

Object * obj = new Object(&anotherObject);

创建另一个对象的副本?

6 个答案:

答案 0 :(得分:27)

不,如果某个功能需要参考:

void f1( Object & o );   // call by reference

然后没有复制。如果函数采用值:

void f2( Object o );   // call by value

然后编译器使用复制构造函数创建一个副本。

是的,当你说:

Object * obj = new Object(anotherObject);   // not &anotherObject

复制构造函数是显式使用的(假设anotherObject的类型为Object。)这里使用new并没有什么神奇之处,但是 - 在这种情况下:

Object obj2(anotherObject);

也使用了复制构造函数。

答案 1 :(得分:7)

如果方法将对象的引用作为参数,则不会调用复制构造函数。如果是这种情况,那么对复制构造函数本身的调用将导致无限循环(因为它将引用作为参数)。

该行不是调用复制构造函数的有效方法。它期望引用作为参数,而不是指针。

答案 2 :(得分:3)

您正在进行方法调用这一事实并不重要。函数调用期间的引用参数初始化与独立引用初始化没有区别,并且受相同规则的约束。

引用初始化规则有点复杂,但底线是如果初始化器是左值(在你的情况下方法调用中的参数),并且引用的类型与引用的类型相同初始化程序(即参数的类型与参数类型相同),然后直接绑定引用。即没有创建副本。

Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying

如果不满足这些要求(例如,如果初始化程序是rvalue,那么一切都取决于)。在某些情况下,可能会发生复制。例如

const Object &tr = Object();

可以被编译器解释为

const Object &tr = Object(Object(Object(Object())));

具有依赖于实现的有限数量的复制。当然,出于效率原因,编译器通常会尝试不创建不必要的副本,即使它们被允许复制也是如此。

经常激起关于编译器复制行为有效性的辩论的典型例子是表达式中的引用初始化,如下所示

Object a;
const Object &r = <some condition> ? a : Object();

熟悉C ++参考语义的人会理解像上面这样的表达式可能是在参考初始化期间执行多余复制的标准权限背后的基本原理。

答案 3 :(得分:1)

两种情况都没有。在第一种情况下,传递对该对象本身的引用并且不创建复制。在第二种情况下,您传递指向object的构造函数的指针,因此不会创建任何副本。所以对象应该有一个类似object(anotherClass*)

的构造函数(不是复制构造函数)

答案 4 :(得分:1)

只有在通过值传递而不是通过引用传递时,才会调用复制构造函数。通过引用不需要复制(这是引用的一部分!)所以没有复制构造函数。

答案 5 :(得分:0)

是的,使用像这样的新位置:

Object dstObject;
new(&dstObject) Object(&anotherObject);