http://www.cnblogs.com/xkfz007/archive/2012/07/21/2602110.html
之前有文章介绍过临时对象和返回值优化RVO方面的问题。见此处。
在C++中,返回对象这一点经常被诟病,因为这个地方的效率比较低,需要进行很多的操作,生成一些临时对象,如果对象比较大的会就会比较耗时。但是在编译器实现的时候,经常是对返回对象的情况进行优化,也就是进行返回值优化 。
在g++中,这个是默认已经进行了优化。以前我希望看看到底C++怎么操作的,但是无法看到,就是因为G++进行了默认的返回值优化RVO。今天在晚上发现可以有一中方法来禁止这个RVO,可以参考这儿。
具体来说就是在编译的时候,加上-fno-elide-constructors这个选项,
#include <iostream>
using namespace std;
class HasPtrMem {
public:
HasPtrMem(): d(new int(3)) {
cout << "Construct: " << ++n_cstr << endl;
}
HasPtrMem(const HasPtrMem & h): d(new int(*h.d)) {
cout << "Copy construct: " << ++n_cptr << endl;
}
HasPtrMem(HasPtrMem && h): d(h.d) { // 移动构造函数
h.d = nullptr; // 将临时值的指针成员置空
cout << "Move construct: " << ++n_mvtr << endl;
}
~HasPtrMem() {
delete d;
cout << "Destruct: " << ++n_dstr << endl;
}
int * d;
static int n_cstr;
static int n_dstr;
static int n_cptr;
static int n_mvtr;
};
int HasPtrMem::n_cstr = 0;
int HasPtrMem::n_dstr = 0;
int HasPtrMem::n_cptr = 0;
int HasPtrMem::n_mvtr = 0;
HasPtrMem GetTemp() {
HasPtrMem h;
cout << "Resource from " << __func__ << ": " << hex << h.d << endl;
return h;
}
int main() {
HasPtrMem a = GetTemp();
cout << "Resource from " << __func__ << ": " << hex << a.d << endl;
}
编译执行:
g++ std_move4.cpp -std=c++11
$./a.out
Construct: 1
Resource from GetTemp: 0x2572010
Resource from main: 0x2572010
Destruct: 1
添加 -fno-elide-constructors 选项,然后编译执行
$g++ std_move4.cpp -std=c++11 -fno-elide-constructors
$./a.out
Construct: 1
Resource from GetTemp: 0x6e7010
Move construct: 1
Destruct: 1
Move construct: 2
Destruct: 2
Resource from main: 0x6e7010
Destruct: 3
可以清晰的看到两次 Move construct 的执行
原文链接: https://www.cnblogs.com/diegodu/p/6492375.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/250087
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!