1

In the following code when I create the object of C then A'a default constructor is getting called through B's constructor, why is that happening?

#include <iostream>
using namespace std;

class A
{
public:
    int a;
    A(int z): a(z) {cout<<"a is "<<a;}
    A() { cout<<" it came here\n";}
};

class B: public virtual A
{
public:
    B(int z): A(z) {cout<<"in B and z is "<<z<<"\n"; }
};

class C:public B
{
public:
    C(int z): B(z) {cout<<" In C\n"; }
};

int main()
{
    C b(6);
    cout<<b.a;
    return 0;
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • There is another alternative for why it is called, directly related to it being a *virtual* base of `B`, from which C is derived. Hint: B's constructor isn't the source, so think again on that. – WhozCraig Sep 25 '13 at 07:40
  • A(int z): a(z) {cout<<"a is "< – Adarsh Kumar Sep 25 '13 at 07:56

1 Answers1

0

That's how virtual inheritance is described in the standard.

[12.6.2] — First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.

In particular, when constructing C, the A subobject is initialized before anything else (including the B subobject). Since A is not in the mem-initializers list of the offending C constructor, the default constructor of A is used for that.

[12.6.2] — Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

Then the B subobject is constructed.

[12.6.2] A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.

: A(z) in the constructor of B is ignored when constructing the B subobject of C.

In the everyday language this means you have to initialize a virtual base class in each direct or indirect derived class, as if it were a direct derived class. If you forget to do so, a default constructor will be forced, with potentially devastating consequences. (That's why you should strive to have either only the default constructor or no default constructor at all in any virtual base class).

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243