Fork me on GitHub

确定对象被使用前已先被初始化

1、一定要手工初始化内置型non-member对象

对于下面一条语句

1 int x;

 如果不对x初始化,则x值是一个半随机数。

2、使用initialization lists来初始化对象的所有成分

  为什么不能用赋值代替初始化列表?

  c++规定:对象成员变量的初始化动作发生在进入构造函数本体之前。所以,不采用初始化列表而采用赋值语句,会先调用每个数据成员的默认构造函数,然后在函数体内赋初始值,之前调用的默认构造函数就浪费了。采用初始化列表,只在初始化列表中调用数据成员的拷贝构造函数。

3、不同编译单元内定义的non-local static对象的初始化次序

先介绍一下什么是non-local static对象

static对象有六种:global对象,定义于n桉树内amespace作用域内的对象,在class内声明为static的对象,在函数内声明为static的对象,在file作用域内声明为static的对象。其中在函数内声明为static的对象又被称为local static对象,而其他五种被称为non-local static对象。

在介绍一下什么是编译单位

产生单一目标文件的那些源码被称为编译单位,基本上包括单一源码文件加上其所包含的头文件。

问题:有两个编译单位,那个单位中声明了一个non-local static对象,其中一个non-local static对象的初始化使用了另一个non-local static对象。代码如下

 编译单元1

1 class FileSystem {
2 public:
3     ...
4     std::size_t numDisks() const;
5     ...
6 };
7 extern FileSystem tfs;

编译单元2

 1 class Directory {
 2 public:
 3     ...
 4     Directory(params);
 5     ...
 6 };
 7 Directory::Directory(params) {
 8     ...
 9     std::size_t disks = rtfs.numDisks();    //使用编译单元1中的non-local static对象
10     ...
11 }

若编译单元2构造了一个non-local static对象

1 Directory temper(params);

在创建Directory对象时,并不能保证tfs已经初始化

解决方法

将non-local static对象写进一个自己专属的函数内,该对象在函数内声明为static,函数返回一个reference指向该对象,这样non-local static对象就被变为local对象。

c++保证:函数内的local static对象会在该函数调用期间首次遇见该对象的定义式子时被初始化。

编译单元1

1 class FileSystem {...}       //同前
2 FileSystem &tfs() {
3     static FileSystem fs;    //创建local static 对象
4     return fs;               //返回该对象的引用
5 }

编译单元2

 1 class Directory{...}    //同前
 2 Directory::Directory(params) {
 3     ...
 4     std::size_t disks = tfs().numDisks();
 5     ...
 6 }
 7 Directory &tempDir() {
 8     static Directory td;
 9     return td;
10 }

 

posted @ 2020-03-23 22:20  最后的战役aag  阅读(169)  评论(0编辑  收藏  举报