在下列情况下,为了让你的程序能够被顺利编译,你必须使用member initialization list
- 当初始化一个
reference member 时; - 当初始化一个
const member 时; - 当调用一个
base class 的constructor,而它拥有一组参数时 - 当调用一个
member class 的constructor ,而它拥有一组参数时;
考虑如下代码:
class Word {
string _name;
int _cnt;
public:
Word() {
_name = 0;
_cnt = 0;
}
};
以下为上述构造函数代码的内部扩张结果:
Word::Word() {
_name.string::string();
string temp = string(0);
_name.string::operator=(temp);
temp.string::~string();
_cnt = 0;
}
对代码反复审查并且修正,可以得到一个更有效率的实现方法:
Word::Word(): _name(0){
_cnt = 0;
}
它会被扩张成这个样子:
Word::Word(){
_name.string::string(0)
_cnt = 0;
}
list 中的项目顺序是由class 中的members 声明顺序决定的,不是由initialization list 中的排列顺序决定的; 如:
Class X {
int i;
int j;
public:
X(int val) : j(val), i(j){}
};
上述代码看起来像是要把j设初始值为val ,再把i 设初值为j .问题在于,由于声明顺序的缘故,initialization list 中的i(j) 其实比j(val) 更早执行.
建议的做法是总是把一个member 的初始化操作和另一个放在一起:
X::X(int val) : j(val) {
i = j;
}
还有一个有趣的问题,initialization list 中的项目被安插到constructor ,会继续保持声明顺序么?也就是说j 的初始化操作会被安插在explicit user assigment 操作(i=j)之前还是之后?;答案是之前,因为initialization list 的项目被放在explicit user code 之前;
|