条款04:确定对象被使用前已先被初始化(Make sure that objects are initialized before they're used.)

1. “将对象初始化”这事,C++似乎反复无常。

 

在某些语境下x保证被初始化(为0),p的成员变量有时候被初始化(为0),有时候不会。

读取未初始化的值会导致不明确的行为。

 

2. 永远在使用对象之前先将它初始化

对内置类型,手动初始化。

至于内置类型以外的任何其他东西,初始化责任落在构造函数(constructors)身上。规则很简单:确保每一个构造函数都将对象的每一个成员初始化。

这个规则很容易奉行,重要的是别混淆了赋值(assignment )和初始化( initialization )。

C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。

构造函数的一个较佳写法是,使用所谓的member initialization list(成员初值列)替换赋值动作:

 

好的习惯:总是在初值列中列出所有成员变量(如果成员变量是const或references,它们就一定需要初值,不能被赋值)。

classes拥有多个构造函数,每个构造函数有自己的成员初值列。这种情况下可以合理地在初值列中遗漏那些“赋值表现像初始化一样好”的成员变量,改用它们的赋值操作,并将那些赋值操作移往某个函数(通常是private,供所有构造函数调用。

 

3. 成员初始化次序

次序总是相同:base classes更早于其derived classes被初始化,而class的成员变量总是以其声明次序被初始化。

当你在成员初值列中条列各个成员时,最好总是以其声明次序为次序。

 

4. static对象

所谓static对象,其寿命从被构造出来直到程序结束为止,因此stack和heap-based对象都被排除。这种对象包括global对象、定义于namespace作用域内的对象、在classes内、在函数内、以及在file作用域内被声明为static的对象。

函数内的static对象称为local static对象(因为它们对函数而言是local),其他static对象称为non-local static对象。程序结束时static对象会被自动销毁,也就是它们的析构函数会在main ( )结束时被自动调用。

 

5. non-local static对象的初始化次序。

C++对“定义于不同编译单元内的non-local static对象的初始化次序并无明确定义。

将每个non-local static对象搬到自己的专属函数内(该对象在此函数内被声明为static)。这些函数返回一个reference指向它所含的对象。换句话说,non-local static对象被local static对象替换了。

这是Singleton模式的一个常见实现手法。

这个手法的基础在于:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。所以如果你以“函数调用”(返回一个reference指向local static对象)替换“直接访问non-local static对象”。

 

此种方式适合inline(频繁调用,短)

但是从另一个角度看,这些函数“内含static对象”的事实使它们在多线程系统中带有不确定性。再说一次,任何一种non-const static对象,不论它是local或non-local,在多线程环境下“等待某事发生”都会有麻烦。处理这个麻烦的一种做法是:在程序的单线程启动阶段( single-threaded startup portion)手工调用所有reference-returning函数,这可消除与初始化有关的,’竞速形势(race conditions )。

 

6. 总结

1)为内置型对象进行手工初始化,因为c什不保证初始化它们。

2)构造函数最好使用成员初值列(member initialization list ),而不要在构造函数本体内使用赋值操作(assignment )。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。

3)为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值