Effective c++ 条款09:绝不在构造函数和析构过程中调用virtual函数

假设现在要创建一个derived class对象,则其构造函数被调用之前,一定会先调用base class的构造函数。
如果我们在base class的构造函数中使用了虚函数,此时被调用的将是base class定义的虚函数而不是derived class的版本,
即:base class构造期间virtual函数绝不会下降到derived class阶层。在base class构造期间,virtual函数不是virtual函数。对象在derived class构造函数开始执行之前不会成为一个derived class对象,在base class构造函数执行期间derived class的成员变量尚未初始化。
同样道理也适用于析构函数,当derived class的析构函数执行后,对象内的derived class成员便呈现未定义值。
通常编译器会给出一个警告,对于这种明显的在构造函数/析构函数内调用virtual函数的行为;
然而当构造函数内需要初始化许多对象,重复相同的工作,此时一个优秀的做法可能是将这些初始化工作放置在另一个初始化函数如init函数内,再在构造函数内调用这个init函数,这时由于虚函数的调用不直接在构造函数内,编译器无法发现这个错误,而运行时将发现调用的虚函数不是我们想要的那个虚函数。
唯一能够避免此问题的方法就是:确定你的析构函数和构造函数都没有调用virtual函数。
但是实现我们希望在构造函数内调用虚函数能够实现的功能呢?我们可以在derived class初始化时把必要的信息传给base class(利用初始化列表),更好的做法是利用static辅助函数创建一个值传递给base class构造函数,也就不可能意外指向“初期未成熟的derived class对象内尚未初始化的成员变量。”

猜你喜欢

转载自blog.csdn.net/unirrrrr/article/details/81144590