Effective C++ 条款9 不在构造和析构函数调用virtual函数

  • 在基类中构造函数中调用virtual函数带来不安全

#include <iostream>

class Transaction {
public:
    Transaction() { logTransaction(); }
 
    virtual void logTransaction() const = 0;
};

class BuyTransaction : public Transaction 
{
public:
    virtual void logTransaction() const{
        printf("BuyTransaction \n");
    };
};
 
class SellTransaction : public Transaction 
{
public:
    virtual void logTransaction() const{
        printf("SellTransaction \n");
    };
};

int main()
{
    SellTransaction *bb = new SellTransaction; //先调用Transaction构造函数,在调用SellTransaction构造函数
    return 0;
}

class Transaction的构造函数调用logTransaction()是有问题的,编译都不会通过。因为Transaction构造函数调用的是自己的virtual函数,main中SellTransaction *bb = new SellTransaction;的操作的流程是:调用SellTransaction的构造函数--->调用Transaction的构造函数。但在构造函数期间,基类与派生类并没有发生virtual的动态绑定,Transaction调用不到SellTransaction的logTransaction函数。简单的说:类构造函数中的virtual函数,不带virtual的性质,就是个普通函数。

  • 为何基类的构造函数不能调用派生类的virtual函数呢?

(1)如果调用基类构造函数,这个时候可以调用派生类的virtual函数(也就是virtual函数绑定好了),那如果派生类的变量未初始化,那么这个派生类的virtual函数的调用将为程序带来不确定性,完全就是引入风险的操作,所以基类构造函数期间virtual函数不是virtual函数。

(2)同理适用于析构函数,当Derived类析构,Base类再析构,Base类的析构函数就不该能调用virtual函数,因为这个时候Derived类已经使用结束了,它的成员函数,变量再使用也是不安全的,所以Derived类析构之后,Base类的析构函数不应该有virtual的使用,

  • 如何在有Derived类对象被构造时,调用正确的Base类函数呢?
  • 通过Derived类向Base类传递参数来调用Base类的构造函数,说白了,就是在Base类写歌函数,不要用virtual
class Transaction {
public:
    explicit Transaction(const std::string& logInfo) { logTransaction(logInfo) }
 
    void logTransaction(const std::string& logInfo) const; // non-virtual
};
 
 
class BuyTransaction : public Transaction 
{
public:
    BuyTransaction(parameters): Transaction(createLogString(parameters)) {}
private:
    static std::string createLogString(parameters);
};
 
class SellTransaction : public Transaction 
{
public:
    SellTransaction(parameters): Transaction(createLogString(parameters)) {}
private:
    static std::string createLogString(parameters);
};

  • 总结:不要再构造,析构函数调用virtual函数。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值