RVO是C++在处理一个函数返回类对象并将返回值赋给另一个对象时,为了减少拷贝构造次数以及析构次数而采用的一种编译器优化技术。
如下一段代码:
#include <iostream>
using namespace std;
int g_construct_count = 0;
int g_copy_construct_count = 0;
int g_destruct_count = 0;
struct Widget
{
Widget(){
cout << "construct count:" << ++g_construct_count << endl;
}
Widget(const Widget& widget){
cout << "copy construct count:" << ++g_copy_construct_count << endl;
}
~Widget() {
cout << "destruct count: " << ++g_destruct_count << endl;
}
};
Widget getWidget() {
Widget w;
return w;
}
int main() {
Widget widget = getWidget();
return 0;
}
下面分别看一下上述代码在g++和vs2013上的运行结果
1)g++在关闭RVO的情况下
@ubuntu:~/work/test/rvo-test$ g++ rvo.cpp -o rvo -fno-elide-constructors
@ubuntu:~/work/test/rvo-test$ ./rvo
construct count:1 //首先在getWidget函数中创建w对象,调用一次构造函数
copy construct count:1 //通过w对象创建一个临时的返回值对象temp,调用一次拷贝构造函数
destruct count: 1 //释放w对象
copy construct count:2 //通过临时的对象temp创建widget对象,调用一次拷贝构造函数
destruct count: 2 //释放临时对象temp
destruct count: 3 //释放对象widget
2)g++在不关闭RVO的情况下(默认是不关闭的)
@ubuntu:~/work/test/rvo-test$ g++ rvo.cpp -o rvo
@ubuntu:~/work/test/rvo-test$ ./rvo
construct count:1
destruct count: 1
在vs下代码调用略有差异
void test() {
Widget widget = getWidget();
}
int main() {
test();
getchar();
return 0;
}
3)vs2013在debug情况下的运行结果
construct count:1
copy construct count:1
destruct count: 1
destruct count: 2
4)vs2013在release情况下的运行结果
construct count:1
destruct count: 1
vs2013 debug模式下对应的伪代码如下:
void getWidget(const Widget &result)
{
Widget w; //创建w对象
result(w); //用w对象拷贝构造result对象;
w.Widget::~Widget(); //w对象析构
return;
}
若将getWidget函数修改为
Widget getWidget() {
return Widget();
}
则vs2013在debug模式下的运行结果如下:
construct count:1
destruct count: 1
其对应的伪代码如下:
void getWidget(const Widget &result)
{
result();
return;
}
NRVO模式则能将如下代码:
Widget getWidget() {
Widget w;
return w;
}
优化成上述伪代码形势
参考:
https://blog.csdn.net/rlyhaha/article/details/80381170
http://www.voidcn.com/article/p-nughucjy-bga.html
网友评论