why don't I get return value optimization in this code?

时间:2016-05-17 11:12:16

标签: c++ constants copy-constructor

Could anyone explain to me the 5th line of the output? I don't understand why the MyClass object b doesn't get assigned returned object c from the func.

class MyClass
{
public:
    int x;
    std::string s;

    MyClass(const MyClass &other);
    MyClass();
    void output();
};

MyClass::MyClass(const MyClass &other): x(2), s("s?") { }
MyClass::MyClass() : x(1), s("s1") { }

void MyClass::output() { cout << x << " " << s << endl; }

MyClass func(MyClass c) //MyClass c = Myclass(a)
{
    cout << "2. in func: "; c.output();
    c.s = "s2";
    cout << "3. in func: "; c.output();
    return c;
}

int main() 
{
    MyClass a;
    cout << "1. "; a.output();
    MyClass b = func(a);
    cout << "4. "; a.output();  
    cout << "5. "; b.output();
}

The output is:

1. 1 s1
2. in func: 2 s?
3. in func: 2 s2
4. 1 s1
5. 2 s?

I understand where do lines 1-4 come from, but I don't get why at the end, the MyClass b.s has a value of s? not the s2. Is it because the const object is created within the func scope?

EDIT: I know that the copy constructor is called when MyClass c object is initialized within the func scope, but how the returned object is not assigned to b ?

3 个答案:

答案 0 :(得分:3)

MyClass b = func(a);

That line will call the copy constructor of MyClass to create b from a. Although it has an =, it does not call the assignment operator; the object hasn't been created yet, so there's nothing to assign to.

An object doesn't need to be const to bind to a const T&, even temporaries can bind to them.

答案 1 :(得分:2)

  

为什么我不在这段代码中获得返回值优化?

原因是你的函数正在返回c,这是一个参数。即使它是一个值,因此也是函数中的本地对象,这是return value optimization(在这种情况下,命名的返回值优化或NRVO)的情况之一C ++标准不允许。如果您要创建c的本地副本,则允许使用RVO:

MyClass func(MyClass c) //MyClass c = Myclass(a)
{
    MyClass d = c;
    cout << "2. in func: "; d.output();
    d.s = "s2";
    cout << "3. in func: "; d.output();
    return d;
}

通过这些更改,我使用最近的clang ++获得以下内容:

  
      
  1. 1 s1
  2.   
  3. 在func:2 s?
  4.   
  5. in func:2 s2
  6.   
  7. 1 s1
  8.   
  9. 2 s2
  10.   

答案 2 :(得分:0)

您在func中返回一个局部变量c。它被复制构造,被复制到b中。你的拷贝构造函数指定s =&#34; s?&#34;所以它被设置为什么。