zoukankan      html  css  js  c++  java
  • 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 的执行

  • 相关阅读:
    直接插入排序
    排序概述
    因为现在这个水平还用不到树和图,所有之后放弃树和图的学习,直接进入排序的学习,现在学到排序树的删除部分,还没学完删除
    检索树
    二叉树的构造
    dedecms 忘记后台密码
    php配置伪静态的方法
    thinkPHP 中去除URL中的index.php
    thinkphp 验证码的使用
    php MySQL数据库操作类源代码
  • 原文地址:https://www.cnblogs.com/diegodu/p/6492375.html
Copyright © 2011-2022 走看看