Calling Member Functions and Virtual Functions from Within Constructors

It is usually safe to call any member function from within a constructor because the object has been completely set up (virtual tables have been initialized and so on) prior to the execution of the first line of user code. However, it is potentially unsafe for a member function to call a virtual member function for an abstract base class during construction or destruction.

Constructors can call virtual functions. When virtual functions are called, the function invoked is the function defined for the constructor’s own class (or inherited from its bases). The following example shows what happens when a virtual function is called from within a constructor:

#include <iostream.h>

class Base
{
public:
    Base();             // Default constructor.
    virtual void f();   // Virtual member function.
};

Base::Base()
{
    cout << "Constructing Base sub-object\n";
    f();                // Call virtual member function
}                       //  from inside constructor.

void Base::f()
{
    cout << "Called Base::f()\n";
}

class Derived : public Base
{
public:
    Derived();          // Default constructor.
    void f();           // Implementation of virtual
};                      //  function f for this class.

Derived::Derived()
{
    cout << "Constructing Derived object\n";
}

void Derived::f()
{
    cout << "Called Derived::f()\n";
}

void main()
{
    Derived d;
}

When the preceding program is run, the declaration Derived d causes the following sequence of events:

  1. The constructor for class Derived (Derived::Derived) is called.

  2. Prior to entering the body of the Derived class’s constructor, the constructor for class Base (Base::Base) is called.

  3. Base::Base calls the function f, which is a virtual function. Ordinarily, Derived::f would be called because the object d is of type Derived. Because the Base::Base function is a constructor, the object is not yet of the Derived type, and Base::f is called.