[C++读书笔记] 成员初始化列表

来源:互联网 发布:java 字符串写入文件 编辑:程序博客网 时间:2024/05/21 19:22

在下列情况下,为了让你的程序能够被顺利编译,你必须使用成员初始化列表:

1. 当初始化一个reference member 时;

2. 当初始化一个const member时;

3. 当调用一个base class 的constructor, 而它拥有一组参数时;

4. 当调用一个member class的constructor, 而它拥有一组参数时。

在这4种情况下,程序可以被正确编译并执行,但效率不高。例如:

class Word {    String  _name;    int        _cnt;public:    // no error, but to naive   Word() {        _name = 0;       _cnt      =  0;    }};
在这里,Word constructor 会先产生一个临时性的 String object, 然后对它初始化,之后以一个assignment 运算符将临时性 object 制定给 _name, 随后再摧毁那个临时性object. 以下是 constructor 可能的内部扩张结果:

Word::Word( /* this pointer goes here */ ){    //调用 String 的default constructor     _name.String::String();    // 产生临时对象   String temp = String(0);   // "memberwise" 地拷贝_name    _name.String::operator=(temp);    // 摧毁临时性对象    temp.String::~String();    _cnt = 0;}
这里有一个明显更有效率的实现方法:

// 较佳的方式Word::Word : _name( 0 ) {    _cnt = 0;}它会被扩张成 这样子:Word::Word(/* this pointer goes here */){    _name.String::String(0);    _cnt = 0;}
成员初始化列表到底会发生什么事情?

假如有这样一个构造函数:

Word::Word() : _cnt( 0 ), _name( 0 ){}

编译器会以以操作initialization list, 以适当顺序在constructor 之内安插初始化操作,并且在任何explicit user code 之前。 例如, 先前的Word constructor 被扩充为:

Word::Word( /* this pointer goes here */ ){    _name.String::String(0);    _cnt = 0;}
有一点微妙的地方要注意:list中的项目顺序是由class中的members声明顺序决定的,不是由initialization list中的排列顺序决定的。 在本例中,_name 被声明于_cnt 之前, 所以它的初始化也比较早。


参考: 《深度探索C++对象模型》 第二章 构造函数语义学

0 0