6

我一直在阅读有关 (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 中的情况如何变化。
4

1 回答 1

6

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

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

3)临时将被复制构造到a

4) 见 1

5) 见 2

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

使用 RVO,2 和 5 可以通过在函数内部通过不可见的引用构造临时来消除。通过进一步的复制省略(不是 RVO),可以消除 3 和 6。所以这给我们留下了 2 个构造,都使用const char*构造函数。

使用 C++11 移动语义,如果编译器足够好来完成所有复制省略,情况就不会改变。如果没有复制省略,那么 2、3、5 和 6 仍然存在,但变成移动而不是复制。然而,与复制省略不同,这些移动不是可选的优化。一个符合要求的编译器必须执行它们,假设它还没有执行复制省略。

于 2012-10-20T10:14:10.400 回答