Sequence of constructor calls in multiple inherita

2019-02-17 07:40发布

问题:

I have tried to find a lot that what if only one class is made virtual in multiple inheritance? The behaviour of constructor call is not clear to me in this case. Let say for example code-

#include<iostream>
using namespace std;
class grand{
public:
    grand(){cout<<"grandfather"<<endl;}
};
class parent1:virtual public grand{   //virtual used only here
public:
    parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public  grand{
public:
    parent2(){cout<<"parent2"<<endl;}
};
class child:public parent1,public parent2{
public:
    child(){cout<<"child"<<endl;}
};
int main()  {
    child s;
    return 0;
}

The output of this code comes as

grandfather
parent1 
grandfather
parent2
child

but in above code if we change this

class parent1:virtual public grand{
public:
    parent1(){cout<<"parent1 "<<endl;}
};
class parent2: public  grand{
public:
    parent2(){cout<<"parent2"<<endl;}
};

to this

class parent1:public grand{   //virtual removed from here
public:
    parent1(){cout<<"parent1 "<<endl;}
};
class parent2:virtual public  grand{  //virtual is added here
public:
    parent2(){cout<<"parent2"<<endl;}
};

output is shown as

grandfather
grandfather    //why parent1 constructor is not called here?
parent1 
parent2
child

My concern is why parent1 constructor is not called after grandfather?

回答1:

The standard says [C++11 section 12.6.2/10] that :

In a non-delegating constructor, initialization proceeds in the following order:

— First, and only for the constructor of the most derived class, virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.

— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

— Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

— Finally, the compound-statement of the constructor body is executed.

So your virtual base classes are always built first... This is really important in the case of virtual base class sharing.