2014-12-13 3 views
5

Я пытался найти много, что Что делать, если только один класс создается виртуальным в множественном наследовании? Поведение вызова конструктора мне непонятно в этом случае. Пусть говорят, например 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; 
} 

Выходной сигнал этого кода приходит в

grandfather 
parent1 
grandfather 
parent2 
child 

, но в коде выше, если мы изменим этот

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

к этому

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;} 
}; 

выход показан как

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

Моя забота почему родительский конструктор не вызван после деда?

+0

Возможный дубликат [Virtual Inheritance, достаточно одного класса?] (Http://stackoverflow.com/questions/13752482/virtual-inheritance-one-class-enough) – Mikhail

+1

Нет, это касается * порядка вызовов * не о * разделение * сам по себе. –

ответ

5

Стандарт говорит [C++ 11 раздел 12.6.2/10], что:

В не делегировании конструктор, инициализации переходит в следующем порядке:

- Во-первых, и только для конструктора самого производного класса, виртуальные базовые классы инициализируются в том порядке, в каком они появляются на первом этапе слева направо, на уровне пересечения направленного ациклического графа базовых классов, где «слева направо» "- порядок появления базовых классов i n список-спецификатор производного класса.

- Затем прямые базовые классы инициализируются в порядке декларации, так как отображаются в списке-спецификаторе-базе (независимо от порядка памяти-инициализаторов ).

- Затем нестатические элементы данных инициализируются в том порядке, в каком они были , объявленные в определении класса (опять же независимо от порядка памяти-инициализаторов ).

- Наконец, выполняется составная инструкция тела конструктора.

Итак, ваши виртуальные базовые классы всегда создаются первыми ... Это действительно важно в случае совместного использования виртуального базового класса.

+0

Спасибо. Как вы сказали, виртуальные классы построены сначала, но после прочтения этого все еще неясно, почему «parent1» не вызывается сразу после «дедушки». Не могли бы вы добавить пример в свой ответ, пожалуйста? – Ankur

+1

Итак, сначала нужно создать виртуальный базовый класс для 'parent2' (правило 1). Затем вам нужно построить 'parent1', а затем' parent2' в этом порядке, поскольку они объявлены такими (правило 2). Но для создания 'parent1' вам нужно сначала создать экземпляр' grand', но не виртуальный (правило 2). Таким образом, это даст вам следующий порядок: 'grand' (виртуальный),' grand' (для parent1), 'parent1',' parent2' (используя виртуальный гранд, построенный в начале), а затем 'child'. –

+0

Спасибо, получил это сейчас :) – Ankur

Смежные вопросы