I have the following c++ code (VS2013 if that matters):
#include <iostream>
using namespace std;
struct A{
A() { cout << "A()" << endl; }
A(int i) { cout << "A(" << i << ")" << endl; }
};
struct B : /*virtual*/ public A{
B(int i) : A(i){ cout << "B(" << i << ")" << endl; }
};
struct C : /*virtual*/ public A{
C(int i) : A(i){ cout << "C(" << i << ")" << endl; }
};
struct D : /*virtual*/ public B, /*virtual*/ public C{
D() : B(2), C(3){ cout << "D()" << endl; }
};
void main() {
D d;
system("pause");
}
The code implements a diamond-shaped inheritance, with 4 inheritances in total: B:A, C:A, D:B, D:C
With none of these inheritances set to virtual
, I get the following output:
A(2) B(2) A(3) C(3) D()
That makes sense. D() first calls B(int x) which first calls A(int x), then calls C(int x) which first calls A(int x), and finally D() itself runs.
But as far as virtual inheritances, I have 4 inheritances, which means that I have a total of 16 combinations of virtual\not-virtual inheritances.
Messing around with the different options yields some very unexpected results, and the more I read about virtual inheritances the more I seem to get confused.
Here are some examples:
- When setting only B:A to
virtual
I get:
A() B(2) A(3) C(3) D()
That makes some sense - B inherits A virtually, and therefore, unless specifically stated otherwise, B(int x) calls A's default constructor.
- When setting only C:A to
virtual
I get:
A() A(2) B(2) C(3) D()
Why do A's constructors both precede B's and C's? That behavior makes no sense to me.
- When setting only D:C to
virtual
I get:
A(3) C(3) A(2) B(2) D()
Why would C's constructor precede B's?
I could go on and on. Some of these combinations lead to very unexpected results (to me, at least).
I know the basics of virtual inheritance and understand them in simple examples, and I've seen many questions regarding it. But some of these behaviors still puzzle me.
Is there any specific set of rules these multiple virtual inheritances go by?
EDIT: I've been redirected to this question: Mixing virtual and non-virtual inheritance of a base class Whlie that helps a lot, I am still confused as to which of A's constructors are called under any specific set of circumstances. I still need some help.