user1999920 user1999920 - 2 months ago 19
C++ Question

Constructor call hierarchy

I'm having a tricky time with calling rules for constructors in a type hierarchy. Here is what I do:

class A{
protected:
int _i;
public:
A(){i = 0;}
A(int i) : _i(i){}
virtual ~A(){}
virtual void print(){std::cout<<i<<std::endl;}
};

class B : virtual public A{
protected:
int _j;
public:
B() : A(){_j = 0;}
B(int i, int j) : A(i), _j(j){}
virtual ~B(){}
virtual void print(){std::cout<<i<<", "<<j<<std::endl;}
};

class C : virtual public B{
protected:
int _k;
public:
C() : B(){_k = 0;}
C(int i, int j, int k} : B(i,j), _k(k){}
virtual ~C(){}
virtual void print(){std::cout<<i<<", "<<j<<", "<<k<<std::endl;}
};

int main(){
C* myC = new C(1,2,3);
myC->print();
delete myC;
return 0;
}


Now, I would like to have new C(1,2,3) call the constructor of B(1,2) which then in turn should call the constructor A(1) to store _i=1, _j=2, _k=3. When creating the instance myC of the class C, for some reason I don't understand, however, the first constructor to be called is the standard constructor of A, i.e., A::A(); This obviously leads to wrong results, as the protected variable _i is assigned the value 0. The constructor A(1) is never called. Why is this so? I find this very counter intuitive. Is there some way to avoid explicitly calling all constructors within the type-hierarchy to achieve the desired behavior?

Thx for the help!

Answer

When you use virtual inheritance, the most derived class must call the constructors for all its virtual bases directly. In this case, the constructor for C must call the constructors for B and A. Since you only call the B constructor, it uses the default A constructor. It does not matter that the B constructor calls another A constructor: since it is a virtual base class, this call is ignored.

You have two ways around this problem: explicitly call the A(int) constructor:

C(int i, int j, int k} : A (i), B(i,j), _k(k){}

or use normal inheritance instead of virtual.

Comments