Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of constructor call in virtual inheritance

Tags:

class A {         int i; public:          A() {cout<<"in A's def const\n";};         A(int k) {cout<<"In A const\n";  i = k; }         };  class B : virtual public A { public:         B(){cout<<"in B's def const\n";};         B(int i) : A(i) {cout<<"in B const\n";}         };  class C :   public B { public:         C() {cout<<"in C def cstr\n";}         C(int i) : B(i) {cout<<"in C const\n";}         };  int main() {         C c(2);         return 0; } 

The output in this case is

in A's def const in B const in C const 

Why is this not entering into in A const

`It should follow the order of 1 arg constructor call. But what actually is happening on deriving B from A using virtual keyword.

There are few more question

Even if I remove the virtual keyword in above program and remove all the default constructor it gives error. So, why it needs the def constructor

like image 747
Kunal Avatar asked May 10 '12 12:05

Kunal


People also ask

In which order constructors are called in inheritance?

For multiple inheritance order of constructor call is, the base class's constructors are called in the order of inheritance and then the derived class's constructor.

In what order the constructor will called when virtual base class & non-virtual base class constructor is present in a class?

The C++ rules say that virtual base classes are constructed before all non-virtual base classes. The thing you as a programmer need to know is this: constructors for virtual base classes anywhere in your class's inheritance hierarchy are called by the “most derived” class's constructor.

What is the order of invocation of constructors and destructors in inheritance?

Answer: C++ constructor call order will be from top to down that is from base class to derived class and c++ destructor call order will be in reverse order.

Which class constructor will be called first?

Explanation: Constructor of class A will be called first. This is because the constructors in multiple inheritance are called in the sequence in which they are written to be inherited. Here A is written first, hence it is called first.


2 Answers

The constructors for virtual base classes are always called from the most derived class, using any arguments it might pass in. In your case, the most derived class doesn't specify an initializer for A, so the default constructor is used.

like image 118
James Kanze Avatar answered Oct 20 '22 16:10

James Kanze


As JamesKanze has explained, in case of virtual inheritance it is the most derived class that calls the virtual base class' constructor. So, if you want A's constructor that takes an integer to be called, you need to add that to C's initialization list.

C(int i) : A(i), B(i) {cout<<"in C const\n";} 

For the second part of your question, default constructors are not required, but then the derived class must call the non-default constructor explicitly, since the compiler is unable to do that for you in the absence of a non-default constructor.

#include <iostream> using namespace std;  class A {   int i; public:   // A() {cout<<"in A's def const\n";};   A(int k) {cout<<"In A const\n";  i = k; } };  class B : virtual public A { public:   // B(){cout<<"in B's def const\n";};   B(int i) : A(i) {cout<<"in B const\n";} };  class C :   public B { public:   C() : A(42), B(42) {cout<<"in C def cstr\n";}   C(int i) : A(i), B(i) {cout<<"in C const\n";} };  int main() {   C c(2), c2;   return 0; } 

This prints out

In A const in B const in C const In A const in B const in C def cstr 
like image 39
Praetorian Avatar answered Oct 20 '22 14:10

Praetorian