侧边栏壁纸
博主头像
如此肤浅

但行好事,莫问前程!

  • 累计撰写 52 篇文章
  • 累计创建 6 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

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

如此肤浅
2022-05-15 / 0 评论 / 0 点赞 / 44 阅读 / 745 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-15,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 在构造和析构期间不要调用 virtual 函数,因为这类调用从不下降至 derived class(比起当前执行构造函数和析构函数的那层)。

class Transaction { // 所有交易的基类
public:
	Transaction();
    virtual void logTransaction() const = 0; // 记录日志
    ...
};
Transaction::Transaction()
{
	...
    logTransaction(); // 构造函数中最后一步是记录日志
}
class BuyTransaction: public Transaction { // 派生类
public:
	virtual void logTransaction() const; // 记录日志
    ...
};

此时,若执行以下这行,会发生什么:

BuyTransaction b;

base class 构造期间 virtua l函数 的调用不会下降到 derived class 阶层!!!

原因: 由于 base class 构造函数的执行更早于 derived class 构造函数,当 base class 构造函数执行时 derived class 的成员变量尚未初始化。如果此期间调用的 virtual 函数下降至 derived classes 阶层,要知道 derived class 的函数几乎必然取用 local 成员变量,而那些成员变量尚未初始化。这可能导致不明确的行为。

根本原因: 在 derived class 对象的 base class 构造期间,对象的类型是 base class 而不是 derived class。不只 virtual 函数会被编译器解析至 base class,若使用运行期类型信息(例如 dynamic_cast(见条款27)和 typeid),也会把对象视为 base class 类型。对于析构函数也是相同的道理。

0

评论区