c++ - (N)RVO 的完整示例

标签 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 move 语义。

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

最佳答案

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

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

3) 临时文件将被复制构造为a

4) 见 1

5) 见 2

6) 见3,但copy会转到b

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

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

关于c++ - (N)RVO 的完整示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12987245/

相关文章:

带有 cURL 的 Android NDK 包含错误

c++ - 通过 move 同一语句中使用的变量进行捕获

c++11 - C++ : For which objects, 是 "moved"意味着超过 "staying valid"?

c++ - NRVO 在抛出异常时有效吗?

c++ - 有没有办法使这个模板特化链接?

c++ - 使应用程序在使用 Win7 功能的 WinXP/Vista 上运行

c++ - 如果我们有 (N)RVO,何时实际调用 move 构造函数?

c++ - 在函数中创建新对象 - C++

c++ - 是否有一种非重复的方式允许程序员在成员初始化的复制和 move 语义之间进行选择?