C++: вопрос списка инициализаторов новичка

Новичок здесь. Я смотрю код компании.

Похоже, что в классе A НЕТ переменных-членов, но в конструкторе A он инициализирует объект B, хотя класс A не содержит никаких переменных-членов типа B (или вообще никаких переменных-членов!).

Наверное, я недостаточно понимаю, чтобы даже задать вопрос... так что же здесь происходит!? Моя интуиция подсказывает, что вам нужна переменная еще до того, как вы попытаетесь ее инициализировать. Как возможно (или что хорошего в этом) инициализировать объект, не имея объекта?

.h:

class A: public B
{
public:
     A(bool r = true);
     virtual ~A;

private:
}

.cpp:

A::A(bool r) : B(r ? B::someEnumeration : B::anotherEnumeration)
{
}

A::~A()
{
}

Пожалуйста помоги.

Спасибо, джбу


person jbu    schedule 03.12.2009    source источник


Ответы (5)


Класс A (публично) наследует от класса B :

class A: public B

Единственный способ инициализации базового класса с параметрами — через инициализатор список.

person luke    schedule 03.12.2009
comment
так что, похоже, поскольку класс A наследуется от класса B, каждый объект типа A содержит скрытую ссылку на объект типа B? - person jbu; 03.12.2009
comment
@jbu: это больше, чем ссылка, это подобъект базового класса. Каждый экземпляр A содержит полный экземпляр B в качестве подобъекта. Наследование используется для выражения отношений, поэтому каждый A также является B. - person CB Bailey; 03.12.2009
comment
Наследование рассматривается как отношение. A является B. Вы можете думать о классе A как о классе B с дополнительными вещами. Вы можете обращаться с A так, как будто это B. - person luke; 03.12.2009
comment
Скорее, наследование public считается отношением "является". - person luke; 03.12.2009

На самом деле это единственный способ вызвать ctor базового класса в C++, поскольку нет такой вещи, как super().

person pmr    schedule 03.12.2009
comment
Да и быть не может, потому что С++ поддерживает множественное наследование. - person Phil Miller; 03.12.2009

class A : public B
{
};

class B
{
  public:
  int x;
};

A является производным типом от B. Или A наследует B.

Так что это актуально...

A a;
a.x = 3;

Остальная часть вашего кода просто вызывает конструктор B при создании A.

person Brian R. Bondy    schedule 03.12.2009

class A: public B
{
public:
     A(bool r = true); // defaults parameter 1 as "true" if no arguments provided ex A *pA = new A();
     virtual ~A;

private:
}

.cpp

A::A(bool r) : B(r ? B::someEnumeration : B::anotherEnumeration)
{
  // calls parent class, and initialize argument 1 with some enumeration based on whether r is true or false
}

A::~A()
{
}
person Daniel    schedule 03.12.2009

Поскольку конструктор не может быть унаследован, члены данных базового класса должны быть инициализированы путем передачи аргумента в конструкторе производного класса и с помощью списка инициализации.

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

person Ashish    schedule 03.12.2009