【寒江雪】确保在对象被使用之前初始化

时间:2021-07-15 19:48:52

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

对于内置类型,必须手工初始化

int x=0;

const char* text=”AAA”;

double d;

cin>>d;//以读取input stream的方式完成初始化

对于内置类型以外的任何东西,初始化责任落在了构造函数身上

要区分赋值与初始化。

考虑不同类的构造函数

class A{int x;int y;string z;};

A(){

x=1;

y=2;

z=”111”;

}

这仅仅是赋值,而初始化应该使用C++的初始化列表

改进如下

class A{int x;int y;string z;};

A()

  :x(0),y(1),z(“aaa”)

{

}

因为这样会调用相应对象的构造函数来对对象进行初始化,而赋值的效果是先调用构造函数,再赋值,发生了两次函数调用

对于以上两点,成员初始化次序是固定的。因此不需要担心成员对象初始化之间的依赖链。不过此链会不会发生死锁,就要靠编码人员自己注意了

 

但另外有一项需要格外注意的问题是,不同编译单元内定义的non-local static对象的初始化次序。

 

static对象,它的寿命从被构造出来知道程序结束为止。这种对象包括,global对象,定义于namespace作用域内的对象,在classes内,在函数内,在file作用域内被声明为static的对象。

函数内的static对象被称为localstatic对象,其他的static对象被称为non-localstatic对象。

程序结束时,static对象会被自动销毁,也就是它们的析构函数会再main()结束时自动被调用

 

编译单元

指产出单一目标文件的那些源码

基本上它是单一源码文件加上其所含入的头文件

 

提出问题:两个源码文件,每一个内含至少一个non-local static对象。如果某编译单元的某个non-localstatic对象的初始化动作使用了另一编译单元内的某个non-local static对象,它所用到的这个对象可能尚未被初始化(由于C++对“定义于不同编译单元的non-local static对象”的初始化次序没有明确的定义)

 

解决方案:运用类似单例模式的方法,为non-local static对象写专属函数,使其成为local static对象。使用这个手法的基础在于:C++保证,函数内的local static对象会在该函数调用期间首次遇上该对象之定义式时被初始化。所以以函数调用返回reference替换直接访问 non-local static对象,你就获得了保证,保证你所获得的那个reference将指向一个历经初始化的对象。

 

例如:有一个FileSystem类的对象

static FileSystem fileSys;

改进为用函数调用获得其引用的方式如下

FileSystem& FileSystemLocalInstance(){

       static FileSystem fileSys;

       return fileSys;

}

【寒江雪】确保在对象被使用之前初始化