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

2. Множественное наследование и виртуальные базовые классы

Класс называют непосредственным (прямым) базовым классом (прямой базой), если он входит в список базовых при определении класса. В то же время для производного класса могут существовать косвенные или непрямые предшественники, которые служат базовыми для классов, входящих в список базовых. Если некоторый класс а яв­ляется базовым для B иB есть база для с, то класс в является непосред­ственным базовым классом для с, а класс а - непрямой базовый класс для с (рис. 10.3). Обращение к компоненту ха, входящему в а и уна­следованному последовательно классами B и C, можно обозначить в классе с либо как А: :ха, либо как В: :ха. Обе конструкции обеспечи­вают обращение к элементу ха класса а.

Рис. 10.3. Прямое и косвенное наследование классов

Иерархию производных классов удобно представлять с помощью направленного ациклического графа (НАГ), где стрелкой изображают отношение "производный от". Производные классы принято изображать ниже базовых. Именно в таком порядке их объявления рассмат­ривает компилятор и их тексты размещаются в листинге программы. Класс может иметь несколько непосредственных базовых классов, т.е. может быть порожден из любого числа базовых классов, например,

class X1 { ... }; class Х2 { ... }; class ХЗ { ... }; class Y1: public X1, public X2, public X3 { ... };

Наличие нескольких прямых базовых классов называют множественным наследованием. В качестве примера рассмотрим производный класс "окружность, вписанная в квадрат". Базовыми классами будут: окружность (circ) и квадрат (square). Приведем вначале их определения:

//CIRC.CPP - определение класса "окружность"

#include <graphics.h>

class circ

( int xc, ус, // Координаты центра

re; // Радиус окружности

public:

// Конструктор:

circ(int xi, int yi, int ri)

{ xc = xi; yc = yi; re = ri; }

// Изобразить окружность на экране:

Void show ()

{ circle(xc,ус,re); }

// Убрать с экрана изображение окружности:

Void hide()

{ int bk, cc;

bk = getbkcolor(); // Цвет фона

cc = getcolor(); // Цвет изображения

setcolor(bk); // Сменить цвет рисования

// Рисуем окружность цветом фона:

circle(xc,ус,re);

// Восстановить цвет изображения:

setcolor(cc); }

};

//SQUARE.CPP - определение класса "квадрат"

#include <graphics.h>

class square

( int xq, yq, // Координаты центра квадрата

lq; // Длина стороны квадрата

// Вспомогательная функция рисования:

Void riesquare(void)

{

int d = lq/2;

line(xq-d,yq-d,xq+d,yq-d) ;

line(xq-d,yq+d,xq+d,yq+d);

line(xq-d,yq-d,xq-d,yq+d);

line(xq+d,yq-d,xq+d,yq+d); )

public:

// Конструктор:

square(int xi,int yi,int li)

{ xq = xi; yq = yi; lq = li; }

// Изобразить квадрат на экране:

Void show()

{ rissquare() ; }

// Убрать с экрана изображение квадрата:

Void hide()

{ int bk, cc;

bk = getbkcolor(); // Цвет фона

cc = getcolor(); // Цвет изображения

setcolor(bk); // Сменить цвет рисования

rissquare(); // Рисуем квадрат цветом фона

setcolor(cc); // Восстановить цвет изображения

}

};

В следующей программе на основе классов circ и square создан производный класс "окружность в квадрате" с именем circsqrt:

//Р10-02.СРР - окружность в квадрате - множественное

// наследование

#include <conio.h> // Для функции getch()

#include "square.cpp" // Определение класса "квадрат"

#include "circ.cpp" // Определение класса "окружность"

// Производный класс - "окружность, вписанная в квадрат";

// Класс circsqrt наследует только методы обоих базовых

// классов. В нем нет наследуемых данных.

class circsqrt : public circ, public square

{ public:

// Конструктор:

circsqrt(int xi, int yi, int ri):

circ(xi,yi,ri), // Явно вызываются конструкторы

square(xi,yi,2*ri) // базовых классов

{}

// Изобразить на экране окружность в квадрате: