首页 > 技术文章 > EC读书笔记系列之5:条款9、条款10

hansonwang99 2015-10-27 22:50 原文

条款9 绝不在构造和析构过程中调用virtual函数

记住:

  ★在构造和析构期间不要调用virtual函数,∵这类调用从不下降至derived class

 -----------------------------------------------------------------------------------

一种非正式的说法:在base class构造或者析构期间,virtual函数不是virtual函数,理由:

表面原因:由于base class构造函数的执行早于derived class的constructor,当base class构造函数执行时derived class的成员变量尚未初始化,使用对象内部尚未初始化的成分可不好!

根本原因:在derived class对象的base class构造期间,对象的类型是base class而不是derived class。C++的任何部分包括virtual函数,运行期类型信息(如dynamic_cast和typeid)等等也就那么看待它。

 

同样的道理也适用于destructor。一旦derived class的destructor开始执行,对象内的derived class成员变量便呈现未定义值,∴C++视它们仿佛不再存在。进入base class的destructor后对象就成为一个base class对象,而C++的任何部分包括virtual函数,运行期类型信息(如dynamic_cast和typeid)等等也就那么看待它。

 

确定你的constructor和destructor都没有调用virtual函数,而它们调用的所有函数也都服从同一约束!!!

 

一种替代的解决方案:

    由于无法使用virtual函数从base classes向下调用,在构造期间,你可以借由“令derived classes将必要的构造信息向上传递至base class构造函数”替换之而加以弥补。

 

后加注:理解此问题时,是不要在基类的constructor中调用虚函数!!!

 

条款10 operator=返回一个reference to *this

记住:

  ★令operator=返回一个reference to *this

 ----------------------------------------------------------

连等时候赋值采用右结合律:

  x = y = z = 15;  解释为: x = ( y = ( z = 15 ) );

 

所以为了实现“连锁赋值”,赋值操作符需返回一个reference指向操作符的左侧实参。

 

= ,+=, -=, *= 等都这么干

推荐阅读