我一直在阅读有关(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)在get_string内部,将使用采用const char*的构造函数构造一个字符串对象(x)。

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

    3)临时文件将被复制到a

    4)见1

    5)见2

    6)参见3,但是副本将转到b
    使用RVO,可以通过一个不可见的引用在函数内部构造临时项,从而消除2和5。通过进一步的复制删除(不是RVO),可以消除3和6。这样就剩下2种构造,都使用const char*构造函数。

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

    07-24 09:49
    查看更多