一、为内置类型对象进行手工初始化,因为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 A 2 { 3 public: 4 A(const string &str): m_str(str) //这里调用的是string的构造函数,直接指定初始化值 5 { 6 } 7 private: 8 string m_str; 9 };
这时的效率比之前的方法要高。因为前者是初始化再赋值,后者直接用指定的值初始化要初始化的对象了。
三、初始化列表中,对于数据成员的初始化顺序,是按照数据成员的在class中声明的顺序,而不是按照在初始化列表中出现的先后顺序。
1 class B 2 { 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 FileSystem 2 { 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 };
时间: 2024-10-09 16:47:52