我一直在阅读有关(N)RVO的内容,并希望获得一个完整的方案说明。我希望这个问题可以帮助其他C++学习者阐明他们的想法。
假设这种情况:
string get_string() {
string x("racecar");
//work on x...
return x;
}
string a( get_string() );
string b = get_string();
请暂时忽略C++ 11移动语义。
被执行? (请指出,它们指向哪些对象)
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 不是可选的优化。假设编译器尚未执行复制省略,则必须执行它们。