条款9:决不在构造和析构过程中调用virtual函数

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

class BuyTransaction:public Transaction
{
public:
virtual void logTransaction()const;
}
BuyTransaction b;

以上代码在基类构造函数里面使用了虚函数,我们本来的想法是,继承函数BuyTransaction在构造时,继承了基类的构造函数,所以相当于在构造函数内部调用了BuyTransaction中的重写的logTransaction函数,但是事实却不是这样的,因为BuyTransaction的构造函数首先先调用基类Transaction的构造函数,而基类的构造函数实现前,BuyTransaction根本就不存在(没构造出来)所以就没有BuyTransaction中的重写的logTransaction函数,所以系统会默认调用基类的那个logTransaction函数。

同理也不能在析构函数中这么做,因为析构函数首先调用基类的析构函数,而这时继承类的函数会被当做不存在而不会被析构。

注意:也不能将虚函数包装在非虚函数里面然后再在构造和析构函数里面调用。

解决方案:在class Transaction内将logTransaction函数改为non-virtual ,然后derived class 构造函数传递必要信息给Transaction构造函数,而后那个构造函数便可以安全的调用non-virtual logTranaction.

猜你喜欢

转载自blog.csdn.net/Du_Shuang/article/details/82995476