Search code examples
c++inheritanceconstructor

Constructor for Multi-level inheritance in C++


Please see following C++ code:

#include <iostream>
using namespace std;

class alpha
{
    int a;
    public:
    alpha () {};
    alpha (int c)
    {
        a = c;
    }
    void showalpha (void)
    {
        cout << "\nalpha, a = " << a;
    }
};

class beta : public alpha
{
    float b;
    public:
    beta () {};
    beta (float c)
    {
        b = c;
    }
    void showbeta (void)
    {
        cout << "\nbeta,  b = " << b;
    }
};

class gamma : public beta
{
    float c;
    public:
    gamma () {};
    gamma (float b, float d): beta (b)
    {
        c = d;
    }
    void showgamma (void)
    {
        cout << "\ngamma, c = " << c;
    }
};
int main ()
{
    gamma A (5.6, 7.6);
    A. showalpha ();
    A. showbeta ();
    A. showgamma ();
    
    return 0;
}

My question is ... Is there any way to modify the constructor of class gamma i.e.

gamma (float b, float d): beta (b)
    {
        c = d;
    }

so that I can initialise all the three classes alpha, beta and gamma using one constructor (and all classes in a multilevel inheritance)? I tried

gamma (int a, float b, float d): alpha (a), beta (b)
    {
        c = d;
    }

but I get the error : type ‘alpha’ is not a direct base of ‘gamma’

I tried a couple of books and a few online resources, but couldnt get an answer. Thank you everyone in advance.


Solution

  • The error message is on spot. gamma only initializes its direct base class object and that in turn must initialize their base class object.

    Consider that base class objects are initialzed in order. When gamma constructor is called, then the very first thing to happen is that the beta subobject is constructed. Part of that is constructing the betas subobject of type alpha. Only after that beta subobject is constructed the rest of gamma gets its turn. At that point the alpha object is already initialized, you cannot initialize it once more.

    As mentioned in a comment, the right approach would be to change beta constructor to:

    beta (float a, float b) : alpha(a), b(b) {}
    

    (also use the member initializer for the data members!)

    So that gamma constructor can be

    gamma (float a, float b,float c): beta (a,c), c(c)  {}
    

    I didn't actually bother to understand what parameter is supposed to be used for which member, but I suppose you get the idea.


    Only for completeness I should mention virtual base classes, because they are an exception from what I wrote above. Virtual base class objects have to be initialized by the most derived class. This is however, just a side effect of how virtual inheritance works. Using virtual inheritance in your example only to let gamma intialize alpha directly would be somewhat backwards.