美文网首页
深度探索C++对象模型:成员变量的初始化列表

深度探索C++对象模型:成员变量的初始化列表

作者: 哪有岁月静好 | 来源:发表于2020-07-14 15:52 被阅读0次

    对 class members 的初始化操作可以放在 member initialization list 或者 construct 中进行,但两者之间是有一些区别的,无论是在效率上还是在语法上。

    何时应该使用 initialization list ?
    在语法方面来说,为了程序可以通过编译,下面几种情况必须使用 initialization list :

    当初始化一个 reference member 时
    当初始化一个 const member 时
    当调用一个 base class 的 constructor ,并且它拥有一组参数时
    当调用一个 member object 的 constructor ,并且它拥有一组参数时

    下面来看一下在效率方面什么时候应该用 initialization list 。首先看下面一段代码:

    class Word {
    public:
      Word() {
        _name = 0;
        _cnt = 0;
      }
    protected:
      String _name;
      int _cnt;
    }
    

    上面这段代码没有语法错误,程序可以正确的编译执行,但是效率上却不尽人意。首先我们来看编译都干了什么,下面是经过编译器扩展后的 constructor 伪码:

    // C++ 伪码
    Word::Word {
      // 调用 _name 的默认构造函数
      _name.String::String();
      // 生成临时对象
      String temp = String(0);
      // 将临时对象 memberwise 拷贝给 _name
      _name.String::Operator=(temp);
      // 销毁临时对象
      temp.String::~String();
      _cnt = 0;
    }
    

    通过编译器扩展后的代码我们可以看到,这种方式的 _name 初始化效率很差,需要产生一个临时对象,多了一次构造、一次拷贝、一次析构的额外操作。不过通过这种初始化方式对 _cnt 并没有什么影响。所以改进后的代码应该是这样的:

    Word::Word() : _name(0) {
      _cnt = 0;
    }
    经过编译器扩展后的伪码类似这样:
    
    Word::Word() {
      _name.String::String(0);
      _cnt = 0;
    }
    

    member initialization list 到底都做了什么?
    通过上面的分析,可以大概看出 initialization list 的作用,具体细节是:

    编译器会一一操作 initialization list ,以适当的次序在 constructor 之内安插初始化操作,并且在任何 explicit user code 之前。

    member initialization list 存在的一些风险
    上面所说的 适当次序 是指 members 在 class 里的声明次序,而不是在 initialization list 的排列次序,所以例如下面这段代码就会问题:

    Class X {
      int i;
      int j;
    
    public:
      X(int val) : j(val), i(j) {
      }
    }
    

    上面代码的本意是先用 val 初始化 j 在用 j 初始化 i ,但实际上 initialization list 的初始化次序是按照 members 在 class 里的声明次序,所以会先初始化 i ,然后才是 j ,而 j 一开始并未进行初始化,导致 i(j) 的结果也无法预料。

    其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。



    相关文章

      网友评论

          本文标题:深度探索C++对象模型:成员变量的初始化列表

          本文链接:https://www.haomeiwen.com/subject/bzhfhktx.html