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

一. 内容

  1. 对于 base-derived 体系,base class 构造函数一定更早被调用,是的,derived class 对象中的 base class 成分会在 derived class 自身成分被构造之前构造妥当。

  2. 这意味着在 base class 里调用的 virtual 函数,尚未动态绑定 derived class 的成分,virtual 函数调用的是 base class 里默认的实现。非正式的说法或者更加易懂:在base class构造期间,virtual函数不是virtual函数。

  3. 如果在 base class 里可以调用 derived class 的 virtual 函数,那么此时 derived class 尚未被初始化,这将是一张通往不明确行为和彻夜调试的直通车票!条款04提醒我们:确定对象使用前先被初始化。

  4. 相同道理也适用于析构函数。析构函数会先一层一层向 base class 调用其析构函数,也就是说最顶层的 base class 的析构函数首先被执行。那么此时 derived class 的成员变量对于 base class 也是尚未初始化的。

    也就是说在 base class 中,就只能访问到 base class 之上的内容,derived class 相当于尚未初始化,访问就是不明确行为。

  5. 一个优秀的做法是将 virtual 函数转变成 non-virtual 函数,并在 derived class 把 non-virtual 函数所需参数传递到 base class 层。也就是说虽然无法使用 virtual 函数从 base class 向下调用,你可以令 derived class 向上传递必要的信息给 base class 构造函数。

  6. 比起在成员初值列给予 base class 数据,更佳的方式利用辅助函数创建一个值给 base class 构造函数,可以令此函数为 private static,使得不会使用那些尚未初始化的成员变量,而是通过客户传进去的自定义参数。

二. 总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值