|
|
В описании класса можно указать список базовых классов с помощью следующих конструкций:
спец-базовых:
: список-базовых
список-базовых:
спецификация-базовых
список-базовых , спецификация-базовых
спецификация-базовых:
полное-имя-класса
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.
| |