?假设有个类的继承体系,用于建模股票交易,例如买入订单、卖出订单等。此类交易是可审计的,因此每次创建交易对象时,都需要在审计日志中创建适当的条目。
class Transaction { // 所有交易的基类
public:
Transaction();
virtual void logTransaction() const = 0; // 创建依赖于类型的日志条目
...
};
Transaction::Transaction() // 基类构造函数的实现
{
...
logTransaction(); // 最后,记录这笔交易
}
class BuyTransaction : public Transaction { // 派生类
public:
virtual void logTransaction() const; // 记录这种类型的交易
...
};
//考虑一下执行这段代码时会发生什么:
BuyTransaction b;
?检测虚函数在构造或析构期间的调用并不总是那么容易。如果类有多个构造函数,每个构造函数都必须执行一些相同的工作,将它们放在私有的非虚拟初始化函数中,以避免代码复制:
class Transaction {
public:
Transaction()
{
init();// 调用 non-virtual...
}
virtual void logTransaction() const = 0;
...
private:
void init()
{
...
logTransaction(); // ...这里调用virtual!
}
};
解决这个问题有很多方法。一种是将logTransaction转换为非虚函数,然后要求派生类构造函数将必要的日志信息传递给基类构造函数。然后该函数可以安全地调用非虚的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);
};