|
在下列情况下,为了让你的程序能够被顺利编译,你必须使用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之前;
|