一、为什么不要在构造和析构中调用virtual函数
- 构造中调用virtual函数,virtual函数不会下降到derived classes。
- 原因:
1)base class构造函的执行早于derived class构造函数,当base class构造函数执行时derived class的成员变量尚未初始化。而derived class的成员函数几乎必定会调用local成员变量,这会导致未定义行为,因此c++禁止;
2)derived class对象的base class构造期间,对象的类型是base class,而不是derived class。使用dynamic_cast和typeid也会把对象视为base clas类型。对象在derived class构造函数开始执行前不会成为一个derived class对象。 这样做的原因就是derived class的专属成分尚未被初始化,将对象的类型视为base class 是安全的。 - 析构函数:一旦derived class 的析构函数开始执行,其内的成员变量便呈现未定义值。所以c++将其视为不存在,进入base class 析构函数后,对象就成为了一个base class对象。而c++的任何部分包括virtual函数、dynamic-cast也这么看待它。
**总结:**进入base class构造函数和析构函数,对象都将视为base class 对象。
二、如何避免在构造函数中调用virtual函数
将base class 中构造函数中要调用的函数声明为non-virtual。通过传参的方式将信息从derived class,derived class 传惨时可使用static 函数,以防止使用derivrd class中未初始化的成员变量。
10 令operator= 返回一个reference to *this
为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参。这个协议也适用于所有赋值相关运算,如operator+=。