我是c ++的新手,我在wiki和本网站上阅读了一些关于返回值优化的内容,但我仍然很好奇以下行为是如何发生的:
using namespace std;
class A
{
public:
A() {cout << "A Ctor" << endl;}
A(const A &a) {cout << "A copy Ctor" << endl;}
};
A Foo()
{
A a;
return a;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Foo()" << endl;
Foo();
cout << "Foo() and new object" << endl;
A b(Foo());
return 0;
}
,输出为:
Foo()
A Ctor
A copy Ctor
Foo() and new object
A Ctor
A copy Ctor
我的问题是,为什么Foo();
和A b(Foo());
都只触发了一个复制构造函数调用?这是否意味着从Foo()
返回的复制值可用于在该位置构造对象b
,以便不需要再次调用b的构造函数?这是基于visual studio 2010。
答案 0 :(得分:1)
返回值优化(RVO)声明编译器可以删除一个或两个副本,但这不是必需的。这意味着:
A a (Foo());
可以自由地执行0,1或2个复制构造函数:
2 - 在函数Foo()中,A a
创建A
。当它尝试返回时,它会将A
复制到返回值中;生成的初始化A a(Foo());
将Foo()
的结果复制到新的A
。
1 - 其中一个副本没有发生(可能是复制到Foo
的返回值。
0 - 这些副本都没有发生。在A a
内创建的Foo
直接成为此行中创建的A
:A a(Foo());
Msdn有很多关于visual c++ compiler handles RVO的详细信息。它有一些简洁的代码示例,可以解释它是如何有效运行的。