4
class A: public B, public C { };

In this case order of execution is:

B(); // base(first)  
C(); // base(second)  
A(); // derived

class A: public B, virtual public C { }; 

But in this case,when i write virtual with class c while inheriting,order of

// execution becomes:  
C(); // virtual base  
B(); // ordinary base  
A(); // derived

i have read somewhere that order of calling constructor depends on the order of declaration while inheriting multiple classes but how does the order of execution gets changed on writing virtual with a class.I am not able to get why i am getting such result.

Holt
  • 36,600
  • 7
  • 92
  • 139
neharika
  • 75
  • 2
  • 8

2 Answers2

5

The virtual base class constructors are always executed first according to the C++ standard. From the working draft N3242, page 272 line 10, we learn that:

  • Virtual base class constructors go first, in the order of a left-to-right depth-first traversal of the inheritance graph.
  • Direct base classes go next, in declaration order.

So the behavior you see is exactly what is required in the C++ standard. It makes sense, because the virtual base classes may show up multiple times in the inheritance and of course they can each only be constructed once. Hence there has to be an initial round of virtual base class construction, followed by the usual non-virtual base class construction.

There is also a nice explanation on this page.

Dan R
  • 1,412
  • 11
  • 21
1

If you have a virtual class as a parent, you cannot hope that initialization goes always in the order of declaration. In fact it is possible that the first (say non-virtual) parent class has itself a dependency on the virtual class. Hence in that case the virtual class must be constructed first.

I think this is the reason why C++ specification says that initializers of virtual parent classes get always executed first. As shown by @Dan Roche there is a predictable order of initialization.

Example:

class B: public A {...}
class C: public B, virtual A {...}

In this example in C's initialization it is not possible to initialize B before A since B's initialization requires A to be initialized first.

another example This example is to show that you shouldn't rely on base class initialization order:

#include <iostream>
using namespace std;

struct A {
  A() {cout<<"A()"<<endl;}
};

struct B {
  B() {cout<<"B()"<<endl;}
};

struct C: virtual A, virtual B {
  C() {cout<<"C()"<<endl;}
};

struct D: virtual B, virtual A, C {
  D() {cout<<"D()"<<endl;}
};  

int  main() {
  cout<<"construct C"<<endl;
  new C;
  cout<<"construct D"<<endl;
  new D;
}

output:

construct C
A()
B()
C()
construct D
B()
A()
C()
D()

As the example shows, when C is constructed as a base class of D, the order of initialization of A and B is reversed. This means that you cannot rely on the order of initialization of virtual base classes if you want that somebody could extend your class.

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64
  • There is a predictable order, defined by the standard, and you can rely on it. – Jonathan Wakely Jul 13 '14 at 13:29
  • can you give me any example where non-virtual class is dependent on virtual class?? – neharika Jul 13 '14 at 13:31
  • @JonathanWakely I suggest to not rely on initialization order of virtual parents because such order could vary if the code (even the private part) of a parent class changes. So: you can rely but better if you don't. – Emanuele Paolini Jul 13 '14 at 13:45