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 );
};
换句话说,既然在基类的构造函数中不能沿着类的继承层次往下调用虚函数,你可以通过在派生类中沿着类的层次结构把必要的构造信息传递到基类的构造器中来补偿这一点。
在这个例子中,请注意BuyTransaction中私有静态函数createLogString的使用方法。通过使用帮助函数来创建一个值并把它传递到基类构造器中,这种方式比起在成员初始化列表中实现基类所需的操作要更方便和更具有可读性。这里我们把该函数创建为static型,这对于偶尔参照引用一下刚产生的BuyTransaction对象的尚未初始化的数据成员是没有危险的。这一点很重要,因为那些数据成员还处于一种未定义的状态中,这一事实解释了为什么在基类的构造或者析构函数中对于虚函数的调用不能首先传递到派生子类中去。
结论
不要在类的构造或者析构过程中调用虚函数,因为这样的调用永远不会沿类继承树往下传递到子类中去。