我很困惑,为什么在我在该函数中创建对象并返回它时,不会调用我已明确定义的复制构造函数。 喜欢在:
ABC function()
{
ABC a;
return a;
}
但是,当我返回函数参数的对象时,调用复制构造函数。它运行得很好。 喜欢在:
ABC function2(const ABC &ab)
{
return ab;
}
但我在上面有问题,因为据说当一个函数按值返回一个对象时,就会调用复制构造函数。
请检查整个代码:
#include<iostream>
using namespace std;
class ABC
{
public:
ABC()
{
cout<<"\nDefault constructor";
}
ABC(const ABC &ac) // copy constructor
{
cout<<"\nCopy constructor called";
}
ABC function()
{
ABC a;
return a;// why here copy constructor is not called?
}
ABC function2(const ABC &ab)
{
return ab;// here copy constructor is calling correctly. No problem!.
}
};
int main()
{
ABC a, b;
b=a.function();
b=a.function2(a);
}
感谢。
答案 0 :(得分:5)
该标准允许一些复制构造函数调用被优化掉,或者标准称之为 elided ,即使相关的复制构造函数具有副作用,例如输出一些文本。构造函数和析构函数调用的数量仍必须匹配。但是例如从函数返回的对象可以直接在调用站点提供的存储中构建,称为RVO,返回值优化。
实际上,复制构造函数假定只能复制,而不管其实际做什么。
在你的第一个例子中,
ABC function()
{
ABC a;
return a;// why here copy constructor is not called?
}
...可以应用RVO,并且使用您的编译器和编译器选项,显然可以应用它。
用你的第二个例子,
ABC function2(const ABC &ab)
{
return ab;// here copy constructor is calling correctly. No problem!.
}
...无法应用RVO,因为在函数体执行时已经构造了ab
对象。