C++ 笔记(二) —— 不要在构造和析构函数中调用虚函数

ilocker:关注 Android 安全(新手) QQ: 2597294287

 1 class Transaction { //所有交易的 base class
 2 public:
 3     Transaction();
 4     virtual void logTransaction() const = 0; //做出一份因类型不同而不同的日志记录
 5  6 }
 7 Transaction::Transaction() {
 8  9     logTransaction();
10 }

derived class:

 1 class BuyTransaction : public Transaction {
 2 public:
 3     virtual void logTransaction() const;
 4  5 }
 6 class SellTransaction : public Transaction {
 7 public:
 8     virtual void logTransaction() const;
 9 10 }

现在执行:

1 BuyTransaction b;

derived class 对象内的 base class 部分首先构造,所以 Transaction 构造函数先被调用。在 Transaction 构造函数中调用的 logTransaction 是 Transaction 的版本,而不是 BuyTransaction 的版本,即使创建的对象类型是 BuyTransaction。

base class 构造期间,virtual 函数绝不会下降到 drived classes 阶层,因为此时 drived class 的成员变量尚未初始化,如果 virtual 函数访问了未初始化的成员变量,就会导致不明确行为,c++ 不允许这种危险操作。

更明确的说:在derived class 对象的 base class 构造期间,对象的类型就是 base class,而不是 derived class,这一点对 RTTI (如 dynamic_cast、typeid) 同样有效。

同样的道理,在执行 base class 的析构函数时,derived class 的析构函数已执行完毕,derived class 的成员变量呈现未定义值,c++ 视他们不存在,此时对象就是一个 base class 对象。

在示例中,构造函数直接调用了 virtual 函数,此外还应注意构造函数和析构函数有没有间接调用 virtual 函数。

学习资料: 《Effective C++》

转载于:https://www.cnblogs.com/ilocker/p/4782807.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值