以下代码:
#include<iostream>
using namespace std;
class Test
{
public:
Test(const Test &t) { cout<<"Copy constructor called"<<endl;}
Test() { cout<<"Constructor called"<<endl;}
};
Test fun()
{
cout << "fun() Called\n";
Test t;
return t;
}
int main()
{
Test t1;
Test t2 = fun();
return 0;
}
关于何时调用复制构造函数,我真的很困惑?就像我运行上面的程序一样,不会调用复制构造函数。这意味着如果我搞乱传递给复制构造函数的参数(消除const关键字),它不应该显示任何编译器错误。但它的表现
“没有匹配函数来调用'Test :: Test(Test)'”
此外,fun()返回一个test类型的对象,它在fun()执行期间创建。为什么不在这里调用复制构造函数?
int main()
{
fun();
return 0;
}
如果我对主函数进行以下更改,为什么复制构造函数只调用一次,而不是两次?
int main()
{
Test t2 = fun();
Test t3 = t2;
return 0;
}
答案 0 :(得分:6)
这是因为复制初始化在这里使用,而不是复制构造函数,因为编译器中启用了NRVO。你应该指定
-fno-elide-constructors
在gcc上标记
C ++标准允许实现省略创建临时 它仅用于初始化相同类型的另一个对象。 指定此选项会禁用该优化,并强制使用G ++ 在所有情况下都要调用复制构造函数。
或在VS上使用cl /Od program.cpp
进行编译(/ O1和/ O2 enables NRVO)
答案 1 :(得分:1)
当我在VS2010中运行您的代码时,我得到了正确的结果:
1
Constructor called
fun() Called
Constructor called
Copy constructor called
2
fun() Called
Constructor called
Copy constructor called
3
fun() Called
Constructor called
Copy constructor called
Copy constructor called
已正确调用复制构造函数。