Конструктор базового класса в списке инициализации
От: Аноним  
Дата: 02.08.05 13:37
Оценка:
Частенько встречается такое:

class D : public B
{
        D():B() {}
};

Для чего явно вызывать B(), ведь он вроде и так сам вызывается или нет?
Re: Конструктор базового класса в списке инициализации
От: Lorenzo_LAMAS  
Дата: 02.08.05 14:13
Оценка: 27 (2)
Здравствуйте, Аноним, Вы писали:

А>Частенько встречается такое:


А>
А>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, значит, компилер не поддерживает такого типа инициализации
Of course, the code must be complete enough to compile and link.
Re[2]: Конструктор базового класса в списке инициализации
От: Evgeniy13 Россия  
Дата: 02.08.05 15:34
Оценка:
L_L>Если раскомменченный вариант не дает 0 0, значит, компилер не поддерживает такого типа инициализации

А стандарт это поддерживает?
Не все в этом мире можно выразить с помощью нулей и единиц...
Re[3]: Конструктор базового класса в списке инициализации
От: Lorenzo_LAMAS  
Дата: 02.08.05 15:36
Оценка:
E>А стандарт это поддерживает?
Да.
Of course, the code must be complete enough to compile and link.
Re[4]: Конструктор базового класса в списке инициализации
От: Lorenzo_LAMAS  
Дата: 02.08.05 15:43
Оценка:

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

Of course, the code must be complete enough to compile and link.
Re[2]: Конструктор базового класса в списке инициализации
От: Аноним  
Дата: 02.08.05 23:21
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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?
Re[3]: Конструктор базового класса в списке инициализации
От: gbt Россия  
Дата: 03.08.05 04:04
Оценка:
Здравствуйте, Аноним, Вы писали:

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-инициализация.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.