logo
volkov / C++ / Бьерн Страуструп-Справочное руководство по С++

R.10 Производные классы

В описании класса можно указать список базовых классов с помощью

следующих конструкций:

спец-базовых:

: список-базовых

список-базовых:

спецификация-базовых

список-базовых , спецификация-базовых

спецификация-базовых:

полное-имя-класса

virtual спецификация-доступа opt полное-имя-класса

спецификация-доступа virtual opt полное-имя-класса

спецификация-доступа:

private

protected

public

Конструкция имя-класса в спецификации-базовых должна обозначать

ранее описанный класс ($$R.9), который называется базовым по

отношению к определяемому классу. Говорят, что класс является

производным от своих базовых классов. Назначение конструкции

спецификация-доступа объясняется в $$R.11. К членам базового класса,

если только они не переопределены в производном классе, можно обращаться

так, как будто они являются членами производного класса. Говорят,

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

операции разрешения области видимости :: ($$R.5.1) к члену базового

класса можно обращаться явно. Такое обращение возможно и в том случае,

когда имя члена базового класса переопределено в производном классе.

Производный класс сам может выступать как базовый при контроле

доступа, см. $$R.11.2. Указатель на производный класс может неявно

преобразовываться в указатель на однозначно определенный и доступный

базовый класс ($$R.4.6). Ссылка на производный класс может неявно

преобразовываться в ссылку на однозначно определенный и доступный

базовый класс ($$R.4.7).

Рассмотрим пример:

class base {

public:

int a, b;

};

class derived : public base {

public:

int b, c;

};

void f()

{

derived d;

d.a = 1;

d.base::b = 2;

d.b = 3;

d.c = 4;

base* bp = &d; // стандартное преобразование derived* в base*

}

Здесь присваиваются значения четырем членам d, а bp настраивается

на d.

Класс называется прямым базовым, если он находится в списке-базовых,

и косвенным базовым, если сам не являясь прямым базовым, он служит

базовым для одного из классов списка-базовых.

Отметим, что в обозначении имя-класса :: имя конструкция, имя может

быть именем члена косвенного базового класса. Такое обозначение

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

Приведем пример:

class A { public: void f(); }

class B : public A { };

class C : public B { public: void f(); }

void C::f()

{

f(); // вызов f() из C

A::f(); // вызов f() из A

B::f(); // вызов f() из A

}

Здесь дважды вызывается A::f(), поскольку это единственная функция f()

в классе B.

Инициализация объектов, представляющих базовые классы, задается

в конструкторах, см. $$R.12.6.2.