Effective-cpp-#9

Never call virtual functions during constructions or destructions

声明结论:不应该在构造函数和析构函数执行期间调用虚函数

动机

如果基类中定义了一个虚函数,那么在派生类中

  • 如果是构造函数调用了该虚函数
    • 那么虚函数起不到多态作用,原因是派生类的构造顺序是先基类后派生类,而此时基类中如果调用了虚函数,那么该虚函数的调用版本为基类的版本。因为在基类构造时,派生类的成员变量还没初始化,因此C++拒绝调用派生类版本的虚函数;
  • 如果是析构函数调用了该虚函数
    • 同理,析构函数的析构顺序是先派生类后基类,如果派生类析构完成员变量后,这些成员变量变成了未定义的。而此时如果到基类的析构函数,那么调用的版本变成了基类版本;

方法

如果真的要在构造函数中调用一个动态函数,那么可以把该函数改造为non-virtual,然后将该函数的信息向上传给基类的构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
class Transaction{
public:
explict Transaction(const std::string& logInfo){logTransaction(logInfo);}
void logTransaction(const std::string& logInfo) const;
};

class BuyTransaction:public Transaction{
public:
BuyTransaction(para):Transaction(createLogString(parameters)){}//向上传递信息
private:
static std::string createLogString(para)
}

建议

  • 构造和析构函数期间不要调用virtual函数。。。。