条款04:确定对象被使用前已先被初始化
? ? 读取未初始化的值会导致程序发生不明确的行为。对于内置类型以外的其他任何类型,初始化的责任落在了构造函数身上。
? ? 在落实这个规则的时候要注意,不要混淆了赋值和初始化?。
? ??
class ca{
int a;
};
class cb{
int a;
string b;
vector<ca> c;
cb(const int& aa,const string& bb,const vector<ca> cc){
a=aa; //这些都是赋值!
b=bb; //而不是初始化!
c=cc;
}
};
? ? ?对于上面的程序,并不是高效率的做法,在构造函数内,变量都不是被初始化,而是被赋值(内置类型除外)。这意味着,首先调用默认的构造函数来为bb,cc设初值,然后再立刻为他们赋值。默认构造函数所做的工作就被浪费了。
? ? 一种更好的写法是使用成员初值列,代码如下
class cb{
int a;
string b;
vector<ca> c;
cb(const int& aa,const string& bb,const vector<ca> cc):
a(aa),
b(bb),
c(cc){}
};
? ? ?对于大多数类型而言,比起现调用default构造函数再调用赋值操作符,单调用一次copy构造函数是更高效的。
? ? 请立下一个规则,规定总是在初值列中列出所有的成员变量,以避免某些变量未被初始化。
? ? 有些情况下,即使面对的成员变量是内置类型,也必须要用初值列,而不能被赋值(例如const变量和引用变量)。
? ? class内变量初始化的顺序总是和他们在类内声明的顺序是相同的。为了方便阅读,在成员初值列中列出各个成员时,总是按照其声明的次序为次序。
?
? ? 请以local static代替non-local static。
? ? 例如我们在文件1中定义 int a = 1;
? ? ? ? ? ?我们在文件2中定义 extern int a;int b = a*3;
? ? ?如果文件2在文件1之前被调用,那么b值就有可能是垃圾值。为了避免这种问题,我们应该避免使变量具有全局的作用域?,具体的做法就是以local static来代替non-local static,代码如下
int& getA(){ //文件1中
static int a = 1;
return a;
}
int b = getA()*3;//文件2中
?这样做就能保证a的初始化在前了
?
原文:http://bbezxcy.iteye.com/blog/2240635