[英]Does a return by value call the copy constructor or the copy assignment operator?
假设编译器中没有返回值优化。
在c ++中,当对象按函数返回值时,真正的步骤如下,我是否正确? 总共,第三次调用构造函数。
本地 (普通构造函数)-> 临时 (副本构造函数)---> 外部 (副本构造函数或副本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?
如果我在第一部分中是正确的,那么如果启用了返回值优化怎么办?
这个问题让我思考,因此从这个意义上讲,这是一个好问题。 我在Visual Studio C ++ Express 2010上的“调试”模式下运行了以下测试代码。
#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似乎是正确的。 构造外部“ Foo”之后,将在函数内部构造“ Foo”对象。 然后,使用复制构造函数创建另一个对象,最后调用赋值运算符将结果复制到对象a。
返回值的优化将取决于编译器和设置。 例如,当我在发布模式下构建和运行时,没有调用复制构造函数,这表明该临时对象仅用于调试模式。 (我不是这个主题的专家。)
C ++中的复制省略/返回值优化允许它跳过调用复制构造函数。
情况1,您在返回中使用副本构造并构建“外部”实例。 这些都可以被忽略。 C ++允许ellide即使他们有可衡量的副作用,这些函数调用-无作为,如果规则适用。
情况2,您正在使用赋值运算符将您的值添加到变量“外部”中,“按原样复制”省略例外不适用于此处。 因此,您将获得一个赋值运算符调用,除非编译器由于没有副作用而可以安全地退出它。 在后一种情况下,编译器可以自由选择,但是根据定义,很难告诉您发生了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.