Ответ 1
Конструктор базового класса вызывается в обоих случаях.
Вот ссылка в статью с дополнительной информацией.
class A : public B
{
...
}
// case I : explicitly call the base class default constructor
A::A() : B()
{
...
}
// case II : don't call the base class default constructor
A::A() // : B()
{
...
}
Случай II равен случаю I?
Для меня я предполагаю, что конструктор по умолчанию базового класса B НЕ вызывается в случае II. Однако, несмотря на то, что я придерживаюсь этого предположения, я провел тест, который доказывает обратное:
class B
{
public:
B()
{
cout << "B constructor" << endl;
}
};
class A : public B
{
public:
A()
{
cout << "A constructor" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
return 0;
}
//вывод из VS2008
B constructor
A constructor
Press any key to continue . . .
Конструктор базового класса вызывается в обоих случаях.
Вот ссылка в статью с дополнительной информацией.
Если конструктор базового класса не принимает никакого аргумента, то явное упоминание его в списке инициализации не требуется.
Чтобы завершить учебный опыт и углубить понимание, вы можете немного изменить ситуацию. Например, что происходит, когда B
не имеет конструктора по умолчанию? Он даже компилируется? Другие незначительные модификации, подобные этому, обеспечат отличный опыт обучения.
Тем не менее, по моему опыту, это вообще лучше сделать
A::A() : B() { ... }
чем
A::A() { ... }
потому что первый более явный, и вам будет нужно подумать о том, что происходит с инициализацией базового класса. Вероятно, вы избегаете скрытого поведения, явно описывая вещи.
Если B
не имеет объявленного конструктора, поведение отличается. Для сравнения:
struct SimpleAggregate {
int a;
float b;
};
struct ClassWrapper : SimpleAggregate {
ClassWrapper() : SimpleAggregate() { }
};
ClassWrapper w;
Теперь w.a
и w.b
гарантированы равными нулю. Если бы вы отказались от явной инициализации базового класса, они имели бы неопределенные значения.
Возможно, вам неизвестно, что, несмотря на синтаксис, вышеупомянутое использование SimpleAggregate()
не вызывает конструктор по умолчанию. Это просто значение инициализирует базовый класс (у нас есть несколько хороших ответов здесь, в Stackoverflow о том, что такое инициализация значения), не вызывая конструктор по умолчанию, потому что ни один пользователь не объявлен.
Каждый класс, полученный из другого класса, должен вызывать конструктор базового класса. Производный класс может быть построен только после того, как все базовые классы полностью построены. Поэтому не имеет значения, вы вызываете конструктор базового класса или нет. Если вы не вызываете, если для компилятора доступен конструктор по умолчанию, он будет вызываться. В противном случае компилятор будет вызывать ошибку.