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 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

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

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

一.概述 手工初始化内置类型对象 构造函数的成员初始化列表 static对象的初始化:包括non-local static和local static 二.细节 1. 你的构造函数使用了成员初始值列表了咩 不使用初始值列表: class A { public: A(const string &s, int i) { //下面都是赋值,而非初始化 s = name; score = i; } private: string name; int score; }; 使用初始值列表: class A {

Effective C++ 之 Item 4:确定对象被使用前已先被初始化

Effective C++ Effective C++ Effective C++ Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Item 4. 确定对象被使用前已先被初始化 (Make sure that objects are initial

[effictive c++] 条款04 确定对象被使用前已被初始化

成员初始化 在c和c++ 中,使用为初始化的类型常常会引发不可预料的错误,从而使得我们要花费巨大的时间用于调试查找问题,所以确定对象被使用前已被初始化是个很好的习惯. 永远在使用之前对对象进行初始化.对于无任何成员的内置类型,你必须手工完成初始化操作.因为c++不保证初始化他们. 内置类型意外的其他东西,初始化责任落在构造函数身上.但要注意区分构造函数中的变量是赋值还是初始化.举个例子 class PhoneNumber{...}; class ABEntry{ public: ABEntry(

《Effective C++ 》学习笔记——条款04

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************  一. Accustoming Yourself to C++ Rules 4: Make sure that objects are initialized before they're used 条款4:确定对象被使用前已先被初始化 一.原因: 关于"将对象

Effective C++ 条款四 确定对象被使用前已被初始化

1.对于某些array不保证其内容被初始化,而vector(来自STL)却有此保证. 2.永远在使用对象前初始化.对于无任何成员的内置类型,必须手工完成.      int x = 0;      const int * p = &x; 3.不要混淆赋值与初始化的区别.一般初始化在定义的时候一起进行.而赋值是在定义之后的动作.      比如说在某一个类中的构造函数中,函数的行为都是赋值操作,而非初始化操作.      一般来说,对象的成员变量的初始化动作发生在进入构造函数本体之前.所以,我们一

Effective C++ Item 4 确定对象被使用前已先被初始化

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验1:为内置对象进行手工初始化,因为C++不保证初始化它们 示例: int x = 0;//对int进行手工初始化 const char *text = "A C-style string"; //对指针进行手工初始化 double d; std::cin >> d;//以读取input stream的方式完成初始化 经验2:构造函数最好使用成员初值列 (membe

effective c++学习笔记条款4-7

条款4:确定对象被使用前已经初始化 一. 变量在不同情况下可能会初始化,也可能不会初始化. 注意初始化和赋值的区别. 1.在类中内置类型不会发生隐式初始化,自定义有默认构造函数的能被默认初始化 所以在构造类时务必初始化内置类型,最好给自定义的对象显示初始化避免在函数体中赋值浪费资源. 2.内置类型在函数体内不会初始化,在函数体外自动初始化为0. 二. 1.const和引用类型必须初始化,不可能赋值 三 1.当类实在是有较多构造函数,并且总是要对一些成员数据重复初始化,可以考虑将那些“赋值和初始化

Effective C++ 条款4 确定对象被使用前已被初始化

1. 对于内置类型,如果变量在全局作用域内定义,默认初始化为0,如果变量在局部作用域内定义,默认不进行初始化; 对于类类型,默认调用默认构造函数进行初始化,如果没有默认构造函数,则必须显式初始化. 2. 构造函数对成员进行初始化的动作发生在初始化列表中而不是函数体内,在函数体内进行的"初始化"实际上是赋值,对于类类型,降低了程序效率,对于内置类型在初始化列表还是在函数体内初始化对于效率没有影响,但在某些特殊情况(例如const变量和引用)必须在初始化列表进行初始化. 3. 类类型的构造

条款4:确定对象被使用前已被初始化

一. 永远在使用对象之前将它初始化 1.对于内置类型,手动完成初始化. 例如:int =0; 2.除了内置类型之外的类型,由构造函数进行初始化:确保每个构造函数都将对象的每一个成员进行了初始化. 二. 特别区分"赋值"和"初始化" 例如:有一个类:A中有一个成员变量string  name; 有一个构造函数:A(const string &n){name=n;}//这是赋值操作而非初始化,这里调用了默认构造函数和赋值运算符 A(const string &a