7

Lets look at the following code:

class A{
protected:
  int _val;
public:
  A(){printf("calling A empty constructor\n");}
  A(int val):_val(val){printf("calling A constructor (%d)\n", val);}
};

class B: virtual public A{
public:
  B(){printf("calling B empty constructor\n");}
  B(int val):A(val){printf("calling B constructor (%d)\n", val);}
};

class C: public B{
public:
  C(){printf("calling C empty constructor\n");}
  C(int val):B(val){printf("calling C constructor (%d)\n", val);}
};

int main(void) {
  C test(2);
}

The output is:

calling A empty constructor
calling B constructor (2)
calling C constructor (2)

Could somebody explain to me why the A class constructor is called without any arguments? Additional how can I "fix" this behaviour if I want the B class to inherit virtually from A? (If the inheritance is not virtual - the sample works fine)

Wojciech Danilo
  • 11,573
  • 17
  • 66
  • 132
  • possible duplicate of [Order of constructor call in virtual inheritance](http://stackoverflow.com/questions/10534228/order-of-constructor-call-in-virtual-inheritance) – Captain Obvlious Jun 29 '13 at 13:42
  • 1
    Hasn't this been discussed to death? – Kerrek SB Jun 29 '13 at 13:47
  • the key word `virtual` in inheritance always makes the constructor call the default constructor of the base class even if you specified a non-default constructor in the declaration, based on the inference that the base class will show multiple times in the inheritance tree and you only want the constructor to be called once. Also notice that the default constructor from the virtual inheritance is called before that from the normal inheritance regardless of the order you may have specified. – kwjsksai Jun 29 '13 at 14:46

1 Answers1

10

In c++03 it'd be the same.

Virtual base constructors are always called from the final leaf class. If you want something else than the default constructor for A when instantiating a C, you have to specify it in the constructor of class C too.

C(int val): A(val), B(val) {printf("calling C constructor (%d)\n", val);}
Yohan Danvin
  • 885
  • 6
  • 13