繁体   English   中英

按值返回是否调用复制构造函数或复制赋值运算符?

[英]Does a return by value call the copy constructor or the copy assignment operator?

假设编译器中没有返回值优化。
在c ++中,当对象按函数返回值时,真正的步骤如下,我是否正确? 总共,第三次调用构造函数。

本地 (普通构造函数)-> 临时 (副本构造函数)---> 外部 (副本构造函数或副本Assignemt运算符)

  1. 创建一个本地对象,在这里它调用普通的构造函数;
  2. 使用本地对象创建了一个临时对象,在这里它调用了复制构造函数;
  3. 将临时对象分配给外部的实际对象(a),在这里它调用复制构造函数(case1)或复制赋值运算符(case2)
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM