C++填坑系列:tip4 确保对象使用前被初始化

隐藏

C++的初始化规则较为复杂,对于不同情形下的初始化有不同的约定

例如,对于C-style的数组不会初始化,因为初始化过程会带来运行期成本, 不符合C++高计算效率的宗旨。而对于STL的数组(例如vector)是保证初始化的。

所以按照Effective c++的建议,干脆统统初始化。

内置类型

手工初始化,赋值或者cin >> i

非内置类型

由构造函数实现初始化。

1. 初始化采用初始化列表而非赋值,

这是因为虽然对于内置类型赋值与初始化成本相同,然而,对于大多数非内置类型,如果赋值,则首先调用default构造函数,再调用copy assignment操作符, 如果采用初始化列表,则可以仅调用default或者copy构造函数,效率更高。

此外,即便对于内置类型,如果是const或者reference类型,则一定要初值初始化而不能被赋值。

2. 多个构造函数的情况

多个构造函数往往初始化列表重复,因此可以被优化,将其中合适的(例如内置类型)成员变量放到函数体内,并作为一个private initial函数

3. 初始化顺序

参考自: http://blog.sina.com.cn/s/blog_adb3f26f0101blg0.html

C++为类中提供类成员的初始化列表 类对象的构造顺序是这样的: 1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员 2.进入构造函数后在构造函数中执行一般计算 1.类里面的任何成员变量在定义时是不能初始化的。 2.一般的数据成员可以在构造函数中初始化。 3.const数据成员必须在构造函数的初始化列表中初始化。 4.static要在类的定义外面初始化。 5.数组成员是不能在初始化列表里初始化的。 6.不能给数组指定明显的初始化。

可见base classes总是更早于其derived classes被初始化。如无特别说明,将调用base class的default 构造函数。

同class内,初始化顺序与其在class内的声明顺序相同。

个人分析:这是跟类的数据结构顺序有关的,通常derived 类的顺序是: 其中虚表指针vptr如果没有virtual函数就没有

 [ base member ] [ base vptr ] [ derived class member ] [ derived vptr ]
4. 注意依赖顺序

因为类中定义顺序是固定的,初始化中注意循序和初始化的依赖关系。

-----EOF-----

Categories: c++ Tags: c++