C++中返回对象的情形及RVO

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 的执行

 

posted @ 2017-03-02 20:19  穆穆兔兔  阅读(635)  评论(0编辑  收藏  举报