class Transaction { // 所有交易的base class
public:
Transaction();
virtual void logTransaction() const = 0;// 做出一份因类型不同而不同的日志记录
};
Transaction::Transaction()// base class 构造函数之实现
{
logTransaction(); // 最后动作是记录这笔交易
}
class BuyTransaction: public Transaction { // derived class
public:
virtual void logTransaction() const; // 记录这笔交易
};
class SellTransaction:public Transaction {
public:
virtual void logTransaction() const;
};
BuyTransaction b{};
如果Transaction有多个构造函数, 每个都需执行某些相同工作, 那么避免代码重复的一个优秀做法是把共同的初始化代码放进一个初始化函数如init内:
class Transaction {
public :
Transaction() {
init();
}
virtual void logTransaction() const = 0;
private:
void init() {
logTransaction();
}
};
这种错误不会引发任何编译器的抱怨。 确定你的构造函数和析构函数都没有调用virtual 函数, 而它们调用的所有函数也都服从同一约束。
一种做法是在class Transaction内将logTransaction函数改为non-virtual, 然后要求derived class 构造函数传递必要信息给Transaction构造函数, 而后那个构造函数便可安全调用non-virtual 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);
};
总结:
在构造和析构期间不要调用virtual函数, 因为这类调用从不下降至derived class。