Question

In the next code, building a C class starts with initializing A then B1 and then B2 and at last C class. However, when initializing B1 and B2, the debugger ignored the initialization of A(1) and A(2) (that appear on the intialization list of B1 and B2 in this order) but didn't ignore the initialization of B2(3) at C initialization list.

Why is that?

Thanks in advance.

Here is the code:

struct A { 
    int i; 
    A() { i = 0; } 
    A(int _i) : i(_i) {} 
    virtual void f() { cout << i; } 
}; 

struct B1 : virtual A { 
    B1() : A(1) { f(); } 
    void f() { cout << i+10; } 
}; 

struct B2 : virtual A { 
    B2(int i) : A(2) { f(); } 
}; 

struct C : B1, B2 { 
    C() : B2(3) {} 
};

int _tmain(int argc, _TCHAR* argv[])
{
    C* c = new C();
    return 0;
}
Was it helpful?

Solution 2

That's exactly how compiler avoids "diamond of death". If A(1) and A(2) would be called, means there was base class duplicate initialization , this is the purpose of virtual inheritance - remove ambiguous common base elements.

OTHER TIPS

For virtual bases, the most derived class has to provide the constructor arguments, e.g.:

struct C
    : B1, B2 { 
    C()
        : A(17)
        , B2(3) {} 
};

If the most derived class does not mention the virtual base in its initializer list, the default constructor of the virtual base is used (if there is none, it is an error).

The reason this is done is to avoid ambiguity of which of the derived classes should provide the constructor arguments for the shared virtual base: the most derived class knows best what is actually needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top