2015-08-14 3 views
1

Мой код:Наличие промежуточного класса без выполнения параметризированный конструктор базового класса

class Parent 
{ 
public: Parent() { cout << "Default Parent" << endl; } 
     Parent(int x) { cout << "Parameterized Parent" << endl; } 
}; 
class Child1: virtual public Parent 
{ 
public: Child1() :Parent(10) { cout << "Default Child1" << endl; } 
}; 
class Child2: virtual public Parent 
{ 
public: Child2() :Parent(10) { cout << "Default Child1" << endl; } 
}; 
class GrandChild: public Child1, public Child2 
{ 
public: 
    GrandChild() { cout << "Default GrandChild" << endl; } 
}; 
int main() 
{ 
    GrandChild G; 
    return 0; 
} 

Выход:

default Parent 
default Child1 
default Child2 
default GrandChild 

Я знаю, что здесь наиболее производный класс вызывает конструктор родительского класса по умолчанию, если не указано иное ,

Но почему аргументы конструктора родительского класса с параметрами ChildX никогда не выполнялись? Без классов ChildX класс GrandChild не может существовать (?). Без параметризованного вызова классы ChildX не будут созданы (?).

ответ

2

Я знаю, что здесь самый производный класс вызывает конструктор по умолчанию родительского класса, если не указано иное.

Существует больше, чем это. Самый производный класс всегда несет ответственность за инициализацию виртуальных базовых классов. Без исключений!

Если конструктор самого производного класса не задает mem-initializer для виртуального базового класса, виртуальный базовый класс по умолчанию построен. Не имеет значения, указывают ли «промежуточные» классы mem-initializers для виртуального базового класса. Это просто игнорируется. Они равны только, когда этот класс является построенным наиболее производным классом.

MEM-инициализатор где MEM-инициализатор-идентификатор обозначает виртуальный базовый класс игнорируется во время выполнения конструктора любого класса, который является не самым производным классом.

(C++ 14 стандарт, [class.base.init]/7)

+0

Почему не составители дают предупреждение о игнорируемых инициализации? – InQusitive

+0

@InQusitive Это не заслуживает предупреждения; нет ничего явно неправильного с 'Child1' и' Child2', которые хотят инициализировать виртуальную базу одним способом, когда они являются наиболее производными классами, и 'GrandChild' хочет сделать это по-другому. – Brian

+1

@Brian Существует один специальный случай: в абстрактном классе этот инициализатор никогда не будет выполнен. – curiousguy

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