当我读到有关复制初始化与直接初始化here的内容时。复制构造函数应该在复制初始化时调用。为什么这里复制构造函数不调用?
#include <iostream>
using namespace std;
class A{};
class B{
public:
B(const A &a){cout << "B construct from A" << endl;}
B(const B &b){cout << "B copy constructor" << endl;}
};
int main(){
A a;
B b = a;
return 0;
}
答案 0 :(得分:5)
复制初始化仍然需要复制,我猜这就是正在发生的事情。从理论上讲,临时B
是从a
构造的,复制构造函数用于从临时创建b
。实际上,可以优化副本。
要对此进行测试,您可以将复制构造函数设为私有:
class B{
public:
B(const A &a){cout << "B construct from A" << endl;}
private:
B(const B &b){cout << "B copy constructor" << endl;}
};
并获得编译错误。这意味着编译器期望可以访问复制构造函数,但不需要调用它。
复制省略是唯一可以改变观察行为的情况。
答案 1 :(得分:5)
这是复制Elision 参考1:。
生成临时文件时复制构造函数调用可能由编译器通过内联创建对象进行优化,并且C ++标准明确允许。
在标准中也很好地展示了一个例子:
C ++ 03标准12.2临时对象[class.temporary]
第2段:
[Example:
class X {
// ...
public:
// ...
X(int);
X(const X&);
˜X();
};
X f(X);
void g()
{
X a(1);
X b = f(X(2));
a = f(a);
}
在这里,一个实现可能会使用一个临时构造
X(2)
,然后使用X的copy-constructor将其传递给f()
;或者,可以在用于保存参数的空间中构造X(2)
。此外,临时可用于保存f(X(2))
的结果,然后再将其复制到`b using
X’s copyconstructor; alternatively,
f()’s result might be constructed in b. On the other hand, the expression
a = f(a){{1} } F(一)requires a temporary for either the argument a or the result of
A`。 ]
参考1:
C ++ 03 12.8复制类对象[class.copy]
第12段:
当满足某些条件时,允许实现省略类对象的复制结构,即使该对象的复制构造函数和/或析构函数有副作用.....