(N)RVO的完整示例

时间:2012-10-20 09:51:44

标签: c++ move-semantics nrvo

我一直在阅读关于(N)RVO的内容,并且想要一个完整的场景描述。我希望这个问题能够为其他C ++学习者提供帮助,以澄清他们的想法。

假设这种情况:

string get_string() {
    string x("racecar");
    //work on x...
    return x;
}

string a( get_string() );
string b = get_string();

请暂时忽略C ++ 11移动语义。

  • 如果没有执行(N)RVO,将有多少构造函数/赋值/析构函数 执行? (请指出,他们参考的对象)
  • 如果应用(N)RVO会发生什么变化?
  • 最后,假设std::string支持,C ++ 11中的情况如何变化? 移动的语义。

1 个答案:

答案 0 :(得分:6)

1)在get_string内,将使用构造函数构造一个字符串对象(x),该构造函数采用const char*

2)当函数返回时,内部构造的字符串将被复制构造到调用者空间中的临时字符串对象。

3)临时将复制到a

4)见1

5)见2

6)见3,但副本将转到b

使用RVO,通过不可见的引用构造函数内部的临时值,可以消除2和5。通过进一步的复制省略(不是RVO),可以消除3和6。因此,我们只使用const char*构造函数构建了2个构造。

使用C ++ 11移动语义,如果编译器足够好以完成所有复制省略,则情况根本不会改变。如果没有完成复制省略,则仍然存在2,3,5和6,但是变为移动而不是复制。与copy elision不同,这些移动不是可选的优化。符合标准的编译器必须执行它们,假设它尚未执行复制省略。