c++inheritance

Why is my override method not being called?


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?


Solution

  • 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 while 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.