2016-05-17 30 views
1

任何人都可以向我解释第五行的输出吗?我不明白为什么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.ss?值不是s2 。是否因为在func范围内创建了const对象?

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

+0

它不是S2因为'MyClass的B = FUNC(一);'要求'B'它初始化拷贝构造字符串成员?' –

+2

我想你可能需要澄清为什么你对输出感到惊讶。你的问题比你可能意识到的更微妙,并且没有任何答案能够解决这个问题。提示:另一个标题可能是“为什么我不能在此代码中获得*返回值优化*?” – juanchopanza

+0

@juanchopanza完成了,谢谢 –

回答

2

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

原因是你的函数返回c,这是一个参数。即使它是一个值,因此也是函数中的本地对象,但这是C++标准不允许return value optimization(在本例中,命名为返回值优化或NRVO)的情况之一。如果您要创建的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; 
} 

这些变化,我开始使用最近铛++如下:在

  1. 1 S1
  2. func:2 s?
  3. 在FUNC:2 S2
  4. 1 S1
  5. 2 S2
3
MyClass b = func(a); 

该行将调用MyClass拷贝构造函数从a创建b。虽然它有一个=,它确实是而不是调用赋值操作符;该对象尚未创建,因此没有可分配的内容。

一个对象不需要const绑定到const T&,即使是临时对象也可以绑定到它们。

+0

所以,'func'返回的对象会发生什么? –

+0

@MaTi它在完整表达式的末尾被销毁。 – TartanLlama

+0

@Ma Ti它会被破坏,尝试创建你的用户定义的析构函数来看看发生了什么。 – PcAF

0

你在函数中返回一个局部变量c。它被拷贝构建,被复制到b中。你的拷贝构造函数指定s =“s?”所以这就是它的设置。

+0

那么它在函数的开头和结尾都会得到“复制结构”? –

+0

是的。一次被传递给函数,并且一次被返回。 – SurDin

相关问题