Частенько встречается такое:
class D : public B
{
D():B() {}
};
Для чего явно вызывать B(), ведь он вроде и так сам вызывается или нет?
Здравствуйте, Аноним, Вы писали:
А>Частенько встречается такое:
А>А>class D : public B
А>{
А> D():B() {}
А>};
А>
А>Для чего явно вызывать B(), ведь он вроде и так сам вызывается или нет?
Если базовый класс имеет конструктор по умолчанию, явно тобой определенный, то это просто избыточный код (скорее всего, в 99 % случаев люди пишут не задумываясь).
Но вот если у него нету конструкторов, то имеет место так называемая value инициализация (воспользуйся поиском, эта тема тут несколько раз была), и тут результаты уже разные.
#include <iostream>
struct Base
{
int i_;
int j_;
};
class Derived : public Base
{
public:
Derived(){}// : Base(){}
};
int main()
{
Derived d;
std::cout<<d.i_<<' '<<d.j_<<std::endl;
}
Если убрать коммент то результат будет 0,0 (тут еще важно, чтоб твой компилятор знал, что такое value-инициализация и стэк не был забит нулями, если стэк заполнен нулями (g++, icc), то придется хитрить чтоб увидеть разницу, например выделять блок памяти и мемсетить его какой-нить фигней)
Если раскомменченный вариант не дает 0 0, значит, компилер не поддерживает такого типа инициализации
L_L>Если раскомменченный вариант не дает 0 0, значит, компилер не поддерживает такого типа инициализации
А стандарт это поддерживает?
12.6.2 Initializing bases and members
...
3 The expression-list in a mem-initializer is used to initialize the base class or nonstatic data member subobject
denoted by the mem-initializer-id. The semantics of a mem-initializer are as follows:
— if the expression-list of the mem-initializer is omitted, the base class or member subobject is valueinitialized
(see 8.5);
...
8.5
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
Здравствуйте, Аноним, Вы писали:
L_L>>#include <iostream>
L_L>>struct Base
L_L>>{
L_L>> int i_;
L_L>> int j_;
L_L>>};
L_L>>class Derived : public Base
L_L>>{
L_L>>public:
L_L>> Derived(){}// : Base(){}
L_L>>};
А>Отсюда вытекает такой вопрос. Base у нас был POD объектом. Получается, что после
А>вызова конструктора B() в Derived он перестал им быть? (Ведь POD-объекты не могут их иметь).
А>Или он перестал им быть еще когда от него произвели Derived? Или же вызов B() в списке инициализации Derived эквивалентен
А>такой вот инициализации ={0, 0} и Base продолжает оставаться POD?
Что-то тут путаница какая-то между динамикой и статикой. Утверждать, является ли тип POD или нет мы можем глядя только на его определение, т.е. на
struct Base
{
int i_;
int j_;
};
Такой тип подпадает под определение POD, поэтому он им является и никакое использование типа Base это не изменит.
Base() — это не вызов конструктора (которого у Base нет), а value-инициализация.