Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯМП ответы.doc
Скачиваний:
0
Добавлен:
28.12.2019
Размер:
710.66 Кб
Скачать

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

Рассмотрим приведённый во введении пример. И круг, и треугольник являются фигурами, однако если не использовать специальных средств для явного указания этого факта, компилятор сам не сможет сделать подобный вывод. Соответственно, мы не сможем, например, поместить указатели на объекты классов Circle иTriangle в один список. Такое отношение между классами называют наследованием.

Класс может быть порождён из другого класса, который называется базовым классом производного класса. Класс может быть порождён из одного или нескольких классов. Порождённые классы наследуют свойства базовых классов, включая данные-члены и функции-члены. Кроме того, в производном классе могут быть объявлены дополнительные данные-члены и функции-члены.Объявление производного класса имеет следующий синтаксис: class <имя производного класса> : <спецификатор доступа> <имя базового класса> [, <спецификатор доступа> <имя базового класса> ]

   { ... };

Отношение наследования между классами может быть представлено в графическом виде.

Популярной и эффективной реализацией понятия производных классов является представление объекта производного класса в виде объекта базового класса и информации, относящейся только к производному классу.

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

Если члены базового класса не переопределены в производном классе, они обозначаются и трактуются так же, как и члены производного класса. Говорят, что члены базового класса наследуются производным классом. Операция разрешения области видимости :: может употребляться для явной ссылки на член базового класса. Это обеспечивает доступ к имени, которое переопределено в производном классе.

Возвращаясь к рассматриваемому примеру, мы видим, что круг является фигурой. Поэтому Circle* можно использовать как Shape*. Однако фигура не обязательно является кругом, поэтому Shape* нельзя использовать как Circle*. В общем случае, указатель на производный класс может быть неявно преобразован к указателю на однозначно доступный базовый класс. Ссылка на производный класс может быть неявно преобразована к ссылке на однозначно доступный базовый класс.

class Base

{ public:

int a, b; };

class Derived : public Base

{ public:

int b, c; };

Derived d;

d.a = 1;

d.Base::b = 2;

d.b = 3;

d.c = 4;

Base *bp = &d;

// Инициализация a, унаследованного из класса Base

// Инициализация b из класса Base

// Инициализация b, объявленного в классе Derived

// Преобразуем указатель на класс Derived в указатель на класс Base

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

class A { public: void f(); };

class B : public A { };

class C : public B

{ public:

void f(); void ff(); };

// Класс B является непосредственным базовым классом для класса C,

// а класс A – косвенным базовым классом для класса C

В записи <имя класса>::<имя>   имя класса может быть именем косвенного базового класса, это имя класса определяет класс, в котором начинается поиск имени.

void C::ff()

{ f();

A::f();

B::f(); }

// Вызов функции f() из класса C

// Вызов функции f() из класса A

// Снова вызов функции f() из класса A, т.к. в классе В функция f() не определена