条款9 绝对不要在构造和析构过程中调用virtual函数
看一个例子,用来记录商品的交易如买进和卖出的订单等。
class Transaction
{
public:
Transaction(){ logTransaction(); }
//这里在原书中是以下声明
// virtual void logTransaction() const = 0;
//但是笔者认为纯虚成员函数应该是无法调用的,所以改成了虚函数
virtual void logTransaction() const
{
cout <<"logTransaction log"<<endl;
}
};
class BuyTransaction : public Transaction
{
public:
BuyTransaction(){}
virtual void logTransaction() const
{
cout <<"BuyTransaction log"<<endl;
}
};
class SellTransaction : public Transaction
{
public:
SellTransaction(){}
virtual void logTransaction() const
{
cout <<"SellTransaction log"<<endl;
}
};
根据继承关系可知打印结果
logTransaction log
BuyTransaction log
主要就是要强调析构和构造函数期间不要调用virtual函数,因为这类调用从不下降至derived class。
一个替代的做法就是在基类Transaction中将log函数改为non-virtual函数,然后要求Derived的构造函数传递必要的信息给Transaction的构造函数。
class Transaction
{
public:
Transaction(const string& logInfo)
{
logTransaction(logInfo);
}
void logTransaction(const string& logInfo) const
{
cout <<logInfo<<endl;
}
};
class BuyTransaction : public Transaction
{
public:
BuyTransaction(parameters)
:Transaction(createLogString(parameters))
{}
private:
static string createLogString(parameters);
};