为什么我在这段代码中没有得到 return 值优化?

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

谁能给我解释一下输出的第 5 行?我不明白为什么 MyClass 对象 b 没有从 func.

中分配返回的对象 c
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();
}

输出为:

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

我知道第 1-4 行是从哪里来的,但我不明白为什么最后 MyClass b.s 的值为 s? 而不是 s2。是因为 const 对象是在 func 范围内创建的吗?

编辑: 我知道当 MyClass c 对象在 func 范围内初始化时调用复制构造函数,但是返回的对象如何不分配给 b ?

MyClass b = func(a);

该行将调用 MyClass 的复制构造函数以从 a 创建 b。尽管它有一个 =,但它确实 而不是 调用赋值运算符;该对象尚未创建,因此没有可分配给的对象。

对象不需要 const 绑定到 const T&,甚至临时对象也可以绑定到它们。

你return func 中的一个局部变量c。它被复制构造,被复制到 b 中。您的复制构造函数指定 s="s?" 所以这就是它被设置为的内容。

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

原因是你的函数是returning c,这是一个参数。尽管它是一个值,因此是函数中的局部对象,但这是 return value optimization 的情况之一(在这种情况下, 命名为 return 值优化, 或 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. in func: 2 s?
  3. in func: 2 s2
  4. 1 s1
  5. 2 s2