Inheritance is a feature in OOPs programming paradigm where a class can inherit data members and functions from another class.

To inherit a class, we need to provide the base class name as shown below:

class Base {}
 
class Derived: public Base {}

Where public is an access specifier.

Constructors in inheritance

When an object of Derived class is created, first the base class constructor gets called and after the derived class constructor executes. For example:

#include <iostream>
 
class Base
{
    int m_base{};
 
public:
    Base(int value = 5)
        : m_base{value}
    {
        std::cout << "Base constructor with value " << m_base << '\n';
    }
};
 
class Derived : public Base
{
    int m_derived{};
public:
    Derived(int value = 10)
        : m_derived{value}
    {
        std::cout << "Derived constructor with value " << m_derived << '\n';
    }
};
 
int main(int argc, char const *argv[])
{
    Derived d;
    return 0;
}

Calling the program gives following output:

Base constructor with value 5
Derived constructor with value 10

As we can see that base class default constructor is called and then derived class default constructor is called.

Calling base class constructors

In the above program, base class default constructor is being called implicitly. If we want to provide a custom value to the base class data member, we need to call the base class constructor in the member initializer list of the derived class constructor.

For example:

#include <iostream>
 
class Base
{
    int m_base{};
 
public:
    Base(int value = 5)
        : m_base{value}
    {
        std::cout << "Base constructor with value " << m_base << '\n';
    }
};
 
class Derived : public Base
{
public:
    int m_derived{};
    Derived(int value = 10, int base_value = 5)
        : m_derived{value}, Base{base_value}
    {
        std::cout << "Derived constructor with value " << m_derived << '\n';
    }
};
 
int main(int argc, char const *argv[])
{
    Derived d{20, 1000};
    return 0;
}

The order of calling base class constructor in the member initializer list does not matter and base class constructor would be called first irrespective.

One must think why we can’t just initialize the base class data members in the derived class constructor member initializer list. There is a reason why C++ doesn’t support it. Data members which are const (and references), the are initialized once when they are created in the constructor.

As base class constructor is called first, the creation of the data member has already been done and can’t be changed in the constructor for the derived class.

Also, data member in the base class would be require for other member creation and if data member would be created in the derived class constructor, the value would not be available for the other member to be created.

So, we need to call the base class appropriate constructor in the derived class member initializer list to initialize base class data members.

References

  1. https://www.learncpp.com/cpp-tutorial/constructors-and-initialization-of-derived-classes/