Item 9 避免在ctor和dtor中调用虚函数

本文探讨了C++中基类构造函数内调用虚函数的问题,解释了为何这种调用不会传递到派生类,并提出了替代方案。

看下面的程序有什么问题。

class Transaction { public: Transaction(); virtual void logTransaction() const = 0; // 实际的日志记录在派生类里实现。我们的本意是根据不同的类生成不同的日志 ... }; Transaction::Transaction() { ... logTransaction(); // 但是,此处会调用派生类的实现吗? } class BuyTransaction: public Transaction { public: virtual void logTransaction() const; ... }; class SellTransaction: public Transaction { public: virtual void logTransaction() const; ... };

在基类的构造过程中,虚函数调用不会被传递到派生类中。因为基类的ctor是在派生类之前执行的,这时其数据成员还没有被初始化,即,派生对象还不存在!所以C++拒绝这样做。
不止虚函数,使用到RTTI的部分(dynamic_cast和typeid),在基类的ctor里,都不会被解析成派生类。
ctor和dtor同样。
一些编译器会对此给出警告。

● 注意,还有一种隐藏版本:

class Transaction { public: Transaction() { init(); // init里面调用了虚函数。同样不行! } virtual void logTransaction() const = 0; ... private: void init() { ... logTransaction(); } };

● 如果非要在基类里实现这样的功能,怎么办?下面是一种办法。

class Transaction { public: explicit Transaction(const std::string& logInfo); void logTransaction(const std::string& logInfo) const; ... }; Transaction::Transaction(const std::string& logInfo) { ... logTransaction(logInfo); } class BuyTransaction: public Transaction { public: BuyTransaction( parameters ) : Transaction(createLogString( parameters )) { ... } ... private: static std::string createLogString( parameters ); };

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值