读取未初始化的值会导致不明确的行为,因此在使用对象前一定要初始化对象。
1,对于内置类型,要手工完成初始化工作 例如:
int x = 10; //对int进行手工初始化
const char * text = "hello world"; //手工初始化
2,对于其它类型,使用构造函数,确保每一个构造函数都将对象的每个成员初始化
注意区分初始化和赋值,使用初始化列表和在构造函数中对成员变量使用"="赋值达到的效果是一样的,可是效率是不同的。因为使用赋值之前,系统会先自动调用default构造函数为成员变量初始化初值,之后再赋给这此变量传递进去的值。而使用初始化列表会直接把传递的值赋给成员变量,所以它的效率高。
出现的问题:
1)代码的重复 一个类有多个的构造函数,对于大量的成员变量,多份成员初始化列表会导致代码的重复。解决方法是把那些赋值和初始化性能一样好的成员变量不用初始化列表中初始化,而是放在一个私有的函数中使用赋值操作。多个的构造函数调用这个私有的函数。
2)C++有着固定的成员初始化次序,基类先初始化之后是继承类。而class的成员变量总是以其声明次序被初始化。
3,不同编译单元内定义的non-local static对象的初始化次序
基本概念:
1)static对象 它包括global对象,定义于namespace作用域内的对象,在class,函数,file作用域内被声明为static的对象。函数内的static对象称为local static对象,其它的对象称为non-local static对象。
2)编译单元(translation unit)是指产出单一目标文件(single object file)的那些代码。基本上它是单一源码文件加上其所含入的头文件(#include files)
C++对不同编译单元内定义的non-local static对象的初始化次序没有明确的定义,为了防止一个文件中的代码使用了另一个文件中的没有初始化的non-local static对象,一个技术上的解决的方法就是把non-local static对象变成local static对象,即把这个non-local static对象放在一个函数中,这个函数返回这个对象的引用。这样在使用这个对象时,要调用这个函数,这样达到了初始化这个对象的目的。因为C++保证,函数内的local static对象会在该函数被调用时并且是首次遇上该对象时被初始化。这样的函数可以写成内联函数。具体的例子见书中。
总结:
1,为内置对象进行手工初始化,因为C++不保证初始化它们
2,构造函数最好使用成员初始化列表(member initialization list),而不是在构造函数本体内使用赋值操作(assignment),初始化列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
3,这免除同编译单元内定义的non-local static对象的初始化次序的问题,请以local static对象替换non-local static对象
Effective C++读书笔记之确定对象被使用前已先被初始化
最新推荐文章于 2022-04-19 15:39:39 发布