2

Potentially a simple question. I noticed a number of similar questions, but none of them seemed to solve my problem, hence my post.

Base.h:

class Base
{
public:
    Base();

protected:
    virtual void Create() {}
};

Base.cpp:

Base::Base()
{
    Create();
}

Child.h:

class Child : public Base
{
protected:
    void Create() override;
};

Child.cpp:

void Child::Create()
{
    // Work happens here
}

Create is called on Base instead of Child When I create of Child. Why isn't Create called on Child?

Brian Gradin
  • 2,165
  • 1
  • 21
  • 42

3 Answers3

8

When you call virtual methods from the ctor of the base class, virtual methods of the base class are called. This is how the language is defined. There are reasons for that, like:

void Child::Show()
{
    // Some work that requires data fields of derived class.
}

If you would call Show in derived class from the ctor of the base class, Child::Show would use data fields of Child but the ctor of the derived class has not been called yet.

There is other related point that is nice to be aware of. Imagine:

class Base     // The class is abstract.
{
public:
    Base() { Show(); }

protected:
    virtual void Show() = 0;
};

class Child : public Base
{
protected:
    void Show() override { /* Some work */ }
};

In this case when you will create any instance of Child, the program will simply crash because pure virtual methods are not instantiated yet. This will be done later, when the hidden part the Child's ctor will work. This hidden part of the ctor modifies the VMT (virtual methods table) of the object. Similar story happens when a complex object is being destroyed. The VMT can be modified multiple times depending on the complexity of the chain of the base classes.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
4

Constructors are special. While you're inside a constructor, the derived class hasn't been constructed yet, so it effectively doesn't exist - constructors are executed base first, derived second. Any member calls you make from the base class constructor will be to the base class members.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

Objects are constructed from the ground up.
When you try to invoke Create (and the other member functions) from within the constructor of Base, it picks up the right definition as provided by the given static type, that is Base.
In other terms, do not rely on virtual member functions from within a constructor.

skypjack
  • 49,335
  • 19
  • 95
  • 187