首页 > 代码库 > Effective C++学习笔记 条款04:确定对象被使用前已先被初始化

Effective C++学习笔记 条款04:确定对象被使用前已先被初始化

一、为内置类型对象进行手工初始化,因为C++不保证初始化它们。

二、对象初始化数据成员是在进入构造函数用户编写代码前完成,要想对数据成员指定初始化值,那就必须使用初始化列表。

 1 class A 2 { 3 public: 4     A(const string &str) 5     { 6         m_str = str;     //m_str 的初始化是在进入构造函数中用户自定义编写代码前完成的,所以这里的m_str = str,执行的不是初始化,而是赋值 7     } 8 private: 9     string m_str;10 };

  在数据成员的默认初始化,然后再在构造函数中进行赋值,这样效率较低。下面就是用户直接给数据成员指定初始化值的例子:

1 class A2 {3 public:4     A(const string &str): m_str(str)  //这里调用的是string的构造函数,直接指定初始化值5     {6     }7 private:8     string m_str;9 };

  这时的效率比之前的方法要高。因为前者是初始化再赋值,后者直接用指定的值初始化要初始化的对象了。

三、初始化列表中,对于数据成员的初始化顺序,是按照数据成员的在class中声明的顺序,而不是按照在初始化列表中出现的先后顺序。

1 class B2 {3 public:4     B(const string &str1, const string &str2): m_b(str1), m_a(str2) {}   5     //这里的初始化顺序是先m_a, 后m_b,因为m_a声明在先6 private:7     string m_a;8     string m_b;9 };

四、C++对于“定义于不同编译单元的non-local static对象”的初始化次序无明确定义。

  static对象,指寿命从被构造出来直到程序结束为止,因此排除stack和heap-based对象。其中包括global对象,定义于namespace作用域内的对象,在class内,在函数内以及在file作用域内被声明为static的对象。(注:static对象不只是声明为static的对象)。函数内定义的static对象称为local static对象,其他的static对象就称为non-local static对象

  第一个文件:

1 class FileSystem2 {3 public:4 5     size_t numDisks() cosnt;6 };7 extern FileSystem tfs;

  第二个文件中:

 1 class Directory 2 { 3 public: 4     Directory(params) 5     { 6  7         size_t disks = tfs.numDisks();  // 8         ... 9     }10 };

  当你定义Directory tempDir(params);

  这时由于C++对于定义于不同编译单元的non-local static对象”的初始化次序无明确定义。所以可能在定义 tempDir时,tfs还没有初始化,那么程序就会出现问题

五、对于上述的问题,为免除“跨编译单元之初始化次序”问题,可以使用local static对象替换non-loacl static对象。

 1 class FileSystem {...}; 2 FileSystem& tfs() 3 { 4     static FileSystem fs; 5     return fs; 6 } 7 class Directory 8 { 9     Directory(params)10     {11 12         size_t disk = tfs().numDisks();    //这样就保证每次使用的时候fs一定初始化了13         ...14     }15 };

 

Effective C++学习笔记 条款04:确定对象被使用前已先被初始化