0
Virtual inheritance and non diamond | constructor calls
Hi Refer code below: I am able to understand that it is diamond problem and two copy of vbase class that means two constructor and destructor calls for VBase. If I have virtual inheritance for both A and B, I am clear that only one copy of VBase will ask for one constructor and destructor. My issue comes when either of them is virtual inheritance and other is not. If A is virtual inherited and B is not : case B If B is virtual inherited and A is not : case C Why B and C has different output? Both of them have two copies of VBase , but why A constructor call order is changed ? https://sololearn.com/compiler-playground/cKo4ut9bOJkR/?ref=app
5 Answers
0
Ketan Lalcheta The key is that ALL virtually inherited constructors are resolved BEFORE ANY normally inherited constructors are resolved.
đ case B
Virtual constructor for VBase for A is called before any other constructors.
Which just happens to match order of constructors if no virtual inheritance is used like case A.
Visually you have following:
Virtual VBase(A)
A
VBase(B)
B
C
đ case C
Virtual constructor for VBase for B is called before any other constructors.
THEN normal constructor for VBase for A is called, followed by A, then B (since B's VBase constructor has already been called).
Visually you have:
Virtual VBase(B)
VBase(A)
A
B
C
0
Shardis Wolfe this does not work for below case:
struct D : public VBase
{
D(){cout<<"D\n";}
~D(){cout<<"~D\n";}
};
struct C : A,virtual B,D
In other word, D class is added and virtual inheritance of B and normal inheritance of A and D is used.
0
Ketan Lalcheta I just played around in your code with your suggested changes, and it worked exactly as expected.
Assuming you left A and B same as your base case (non-virtual inheritance from VBase),
Adding D and changing C as outlined produced the following constructor order:
It tries to construct virtual B first, but due to B's inheritance it must construct a normal VBase first. Then it goes back to constructing A then D (with their own VBases) in sequence, and ends with C.
VBase - normal for B
B - Virtual
VBase - normal for A
A
VBase - normal for D
D
C
0
If VBase and then B In your last comment for new case I asked for,
Then why not B is not just after VBase in my original question's case C? There it was half cooked VBase from B and it started with A (VBASE AND A)
0
Ketan Lalcheta It all depends on what is virtual on the right side of any given inheritance declaration.
In your original question, neither A nor B were declared as virtual when you specified C's inheritance. It was VBase you were declaring as virtual in A's or B's inheritance.
Your newer question completely changed that by directly making one of C's parents virtual (B in that case).