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
?
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.