条款04:确定对象在使用前已经被初始化

读取未初始化的值会造成不明确的行为。

  • 对于内置类型来说,我们必须手工完成初始化。
  • 对于类类型来说,这个责任由构造函数来承担,所以构造函数要确保所有的数据成员有被初始化。

例如下面这个构造函数:

ABEntity::ABEntity(const std::string& name, const std::string& address,

                                     const std::list<PhoneNumber>& phones)

                   {

                            theName = name;

                            theAddress = address;

                            thePhones = phones;                         

                   }

注意这是我们新手比较容易犯的一个错误,我们以为上面这个构造函数对成员进行了初始化。其实,这不是初始化,这是赋值。虽然ABEntity可以得到你期望的值。

         C++规定初始化的动作发生在进行构造函数本体之前。

 

比较好的一个做法是使用成员初始化列表:

ABEntity::ABEntity(const std::string& name, const std::string& address,

                                                                                     const std::list<PhoneNumber>& phones)

                                                                                     : theName(name),

theAddress(address),

                                                                                      thePhones(phones){}

基于赋值的那个版本,首先调用default构造函数为theName,theAddress,thePhones设初始值,然后,在函数体内再进行赋值。所以说default构造函数所做的一切都没有用。

 

而基于成员初始值列表的做法是直接调用theName,theAddress,thePhones的copy构造函数。

对于大多数而言,第二种方式每个成员只调用一次copy构造函数的方式高效的多。而对于内置类型来说,采用成员初始化列表与在构造函数内进行赋值的代价是一样的,但为了统一,也把内置类型的初始化放在成员初始化列表。

 

问为什么内置类型的初始化,两种方式一样?

初始化是两个过程:内存分配,填写值。

对于第一种方式,在函数体内进行赋值,是先内存分配,再赋值。对于在成员初始化列表中初始化也是先分配内存,再赋值。两种作法的步骤都一样。

而类成员,第一种方式会导致调用默认构造函数无用功。

 

 

 

posted @ 2012-11-15 22:27  loveyakamoz  阅读(229)  评论(0编辑  收藏  举报