C++ Undefined Behavior Calling (Pure) Virtual Members From Constructor Or Destructor


Example

The Standard (10.4) states:

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.

More generally, some C++ authorities, e.g. Scott Meyers, suggest never calling virtual functions (even non-pure ones) from constructors and dstructors.

Consider the following example, modified from the above link:

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 */ }
};

Suppose we create a sell_transaction object:

sell_transaction s;

This implicitly calls the constructor of sell_transaction, which first calls the constructor of transaction. When the constructor of transaction is called though, the object is not yet of the type sell_transaction, but rather only of the type transaction.

Consequently, the call in transaction::transaction() to log_it, won't do what might seem to be the intuitive thing - namely call sell_transaction::log_it.

  • If log_it is pure virtual, as in this example, the behaviour is undefined.

  • If log_it is non-pure virtual, transaction::log_it will be called.