我一直在阅读有关 (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/