从构造函数或析构函数调用(纯)虚拟成员

标准(10.4) 规定:

可以从抽象类的构造函数(或析构函数)调用成员函数; 对于从这样的构造函数(或析构函数)创建(或销毁)的对象,直接或间接地对纯虚函数进行虚拟调用(10.3)的效​​果是未定义的。

更一般地说,一些 C++权威,例如 Scott Meyers,建议永远不要从构造函数和 dstructors 调用虚函数(甚至是非纯函数)。

请考虑以下示例,从以上链接修改:

class transaction
{
public:
    transaction(){ log_it(); }
    virtual void log_it() const = 0;
};

class sell_transaction : public transaction
{
public:
    virtual void log_it() const { /* Do something */ }
};

假设我们创建了一个 sell_transaction 对象:

sell_transaction s;

这隐式调用 sell_transaction 的构造函数,它首先调用 transaction 的构造函数。当调用 transaction 的构造函数时,该对象尚未属于 sell_transaction 类型,而仅属于 transaction 类型。

因此,transaction::transaction()log_it 的调用,不会做看似直觉的事情 - 即调用 sell_transaction::log_it

  • 如果 log_it 是纯虚拟的,就像在此示例中一样,行为是未定义的。

  • 如果 log_it 是非纯虚拟的,则会调用 transaction::log_it