假设编译器中没有返回值optimizaiton 在c ++中,当对象在函数中返回vaule时,真正的步骤在下面,我是否正确?总的来说,第三次调用构造函数。
本地(普通建筑师) - > temp (复制构造函数)---> 外部(复制构造函数或复制assignemt运算符)
class Name{...};
Name func(){
// ...
Name local;
return local;
}
情形1:
Name outside = func(); // call copy constructor?
情况2:
Name outside;
outside = func(); // call copy assignment operator?
如果我在第一部分是正确的,如果启用了返回值优化会怎么样?
答案 0 :(得分:1)
这个问题让我思考,所以从这个意义上来说这是一个很好的问题。我在Visual Studio C ++ Express 2010中运行下面的测试代码" Debug"模式。
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(int arg) { val = arg; cout<<"Constructor (normal): "<<val<<endl; }
Foo(const Foo& ref) { val = ref.val; cout<<"Copy constructor: "<<val<<endl; }
const Foo& operator=(const Foo& rval)
{
cout<<"Assignment operator from object "<<rval.val<<" to object "<<val<<endl;
val = rval.val;
return *this;
}
int val;
};
Foo process() {Foo t(2); return t; }
int main()
{
Foo a(1);
a = process();
system("pause");
return 0;
}
结果:
Constructor (normal): 1 Constructor (normal): 2 Copy constructor: 2 Assignment operator from object 2 to object 1 Press any key to continue . . .
案例2似乎是正确的。在外部&#39; Foo&#39;构建了'Foo&#39; object是在函数内部构造的。然后使用复制构造函数创建另一个对象,最后调用赋值运算符将结果复制到对象a。
返回值优化将取决于编译器和设置。例如,当我在发布模式下构建和运行时,没有调用复制构造函数,表明临时对象仅用于调试模式。 (我不是这个主题的专家。)
答案 1 :(得分:1)
C ++中的复制省略/返回值优化允许它跳过调用复制构造函数。
案例1,您在返回中使用了复制构造并构建了实例&#34;在&#34;之外。这些中的任何一个或两个都可以省略。 即使C ++具有可测量的副作用,也允许C ++忽略这些函数调用 - 不适用as-if规则。
案例2您正在使用赋值运算符将值输入变量&#34;在&#34;之外,非依赖于复制省略的异常在此处不适用。因此,您将获得一个赋值操作符调用,除非编译器可以安全地忽略它,因为它没有副作用。在后一种情况下,编译器可以自由选择,但根据定义,你很难说出发生了什么。