Effective C++之四

    核心思想:对象使用前必须初始化

    C++对象初始化没有简明的规则。大致而已,出于效率考虑,C++的C部分(参见条款1)不保证进行初始化,而非C的部分能保证初始化。读取未初始化的随机值,将导致未定义的行为,包括程序异常退出。

   

    最好的做法是:在使用前永远进行初始化,对内置数据类型进行手工初始化。

    对于对象而已,初始化的职责落在构造函数上。成员变量初始化的好的做法是使用初始化列表,而不是在构造函数的函数体中赋值。两者之间至少有以下区别:

    - 初始化列表在构造函数体之前执行

    - 如果成员对象有缺省构造函数,又没有写在初始化列表中,C++编译器函数对它进行确省构造。故如果采用初始化列表是调用一次构造,而使用函数体中赋值则调用了一次缺省构造和一次赋值,相对效率较低。

   

    初始化列表需注意以下几点:

    - 初始化的顺序不是按初始化列表中出现的顺序,而是成员变量声明的顺序

    - 基类在派生类前被初始化,以基类声明的顺序

    - 如果存在virtual基类的话,virtual基类在普通基类之前被初始化,顺序是从最深到最浅,从左到右[1]

    - 以下四中情况必须使用初始化列表: 1) const成员变量, 2)reference成员变量, 3)成员对象的构造函数有参数, 4)基类的构造函数有参数。

    - 如果初始化成员变量时调用了成员函数,建议不要在初始化列表中这样做,防止该成员函数中对其他成员变量的依赖问题。[2]。

   

    最后,Mayers谈了不同编译单元(指.cpp文件)中非局部(non-local)静态变量的初始化问题。结论是:其初始化顺序是不定的。有两种解决方案:

    1) 将static变量定义在一个函数内部。局部static变量在第一次使用到时定义,其顺序是固定的

    2) 使用Singleton设计模式。

    但是在多线程环境下仍存在问题,方案1的一种处理方法是在程序启动的单线程环境中访问生成各static对象。Singleton模式的解决方案是采用double-checked locking optimiazation模式[3]。

 

    参考文档:

    [1] 参见《C++对象模型》5.2节

    [2] 参见《C++对象模型》2.4节

    [3] 参见 《面向模式的软件体系结构》之二 4.4节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值