Программирование >>  Дополнительные возможности наследования 

1 ... 124 125 126 [ 127 ] 128 129 130 ... 265


X X X X X X X X X X X X X X х X X .X X X

(l)Circle (2)Rectangle (3)Square (0)Quit:0

В строках 6-15 объявляется класс Shape. Методы GetAreaO и GetPerimO возвращают -1 как сообщение об ощибке, а метод DrawO не выполняет никаких действий. Давайте подумаем, можно ли в принципе нарисовать форму? Можно нарисовать окружность, прямоугольник или квадрат, но форма - это абстракция, которую невозможно изобразить.

Класс Circle производится от класса Shape, и в нем замещаются три виртуальных метода. Обратите внимание, что в данном случае нет необходимости использовать ключевое слово virtual, поскольку виртуальность функций наследуется в производном классе. Тем не менее для напоминания о винртуальности используемых функций не лищним будет явно указать это.

Класс Square производится от югасса Rectangle и наследует от него все методы, причем метод GetPerimO замещается в новом классе.

Все методы должны функционировать нормально в производных классах, но не в базовом классе Shape, поскольку невозможно создать экземпляр формы как таковой. Программа должна быть защищена от попытки пользователя создать объект этого класса. Класс Shape существует только для того, чтобы поддерживать интерфейс, общий для всех производных классов, поэтому об этом типе данных говорят как об абстрактном, или ADT (Abstract Data Type).

Абстрактный класс данных представляет общую концепцию, такую как форма, а не отдельные объекты, такие как окружность или квадрат. В С++ ADT по отнощению к другим классам всегда выступает как базовый, для которого невозможно создать функциональный объект абстрактного класса.

Чистые виртуальные функции

С++ поддерживает создание абстрактных типов данных с чистыми виртуальными функциями. Чистыми виртуальными функциями называются такие, которые инициализируются нулевым значением, например:

virtual void DrawO = 0;

Класс, содержащий чистые виртуальные функции, является ADT. Невозможно создать объект для класса, который является ADT. Попытка создания обьекта для такого класса вызовет сообщение об ощибке во время компиляции. Помещение в класс чистой виртуальной функции будет означать следующее;

невозможность создания объекта этого класса;

необходимость замещения чистой виртуальной функции в производном классе.

Любой класс, произведенный от ADT, унаследует от него чистую виртуальную функцию, которую необходимо будет заместить, чтобы получить возможность создавать объекты этого класса. Так, если югасс Rectangle наследуется от класса Shape, который содержит три чистые виртуальные функции, то в классе Rectangle должны быть замещены все эти три функции, иначе он тоже будет ADT. В листинге 13.8 изменено объявление клас-



са Shape таким образом, чтобы он стал абстрактным типом данных. Остальная часть листинга 13.7 не изменилась, поэтому не приводится. Просто замените объявление класса в строках 7-16 листинга 13.7 листингом 13.8 и запустите профамму.

йисаш 13.1. Д1сир1кт11Ы8 тшы цжиыж

1: класс Shape

2; {

3: public:

4: Shape(){ }

5: -Shape(){ },

6: virtual long GetAreaO = 0; ошибка

7: virtual long GetPerim()= 0;

8: virtual void Draw() = 0;

9: private:

10: } ;

(l)Circle (2)Rectangle (3)Square (O)Quit: 2

X X X X X X X X X X X X X X X X X X X X X X X X

(l)Circle (2)Rectangle (3)Square (O)Quit: 3

X X X X X X X X X X X X X X X X X X X X X X X X X

(l)Gircle (2)Rectangle (3)Square (O)Quit: 0

Как видите, выполнение профаммы не изменилось. Просто теперь в профамме невозможно создать объект класса Shape.

Абстрактные тнны данных

Чтобы объявить класс как абстрактный тип данных, достаточно добавить в него одну или несколько чистых виртуальных функций. Для этого после объявления функции необходимо добавить - о, например:

f;;piiiiiiliiie

virtual void DrawO = 0; чистая виртуальная функция



BbiRDARBiiUB чистых виртувльных функций

Обычно чистые виртуальные функции объявляются в абстрактном базовом классе и не выполняются. Поскольку невозможно создать обьект абстрактного базового класса, как правило, нет необходимости и выполнений чисТой вйртуУьнЬй функции. Класс ADT существует только как объявление интерфейса объектов, создаваемых в производных классах.

Тем не менее все же иногда возникает необходимость выполнения чистой виртуальной функции. Она может быть вызвана из объекта, произведенного от ЛОТ, например чтобы обеспечить общую функциональность для всех замещенных функций. В листинге 13.9 представлен видоизмененный листинг 13.7, в котором класс Shape объявлен как ADT и в программе выполняется чистая виртуальная функция Draw(). Функция замещается в классе Circle, что необходимо для создания обьекта этого класса, но в объявлении замещенной функции делается вызов чистой виртуальной функции из базового класса. Это средство используется для достижения дополнительной функциональности методов класса.

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

йпспнгкг 13.9. Bunmmt чвсгоых ввршуядьпых фувкра

Выполнение чистых виртуальных функций

#include <iostream.h>

class Shape {

public;

Shape(){ } virtual Shape(){ }

virtual long GetAreaO = 0; virtual long GetPerim()= 0; virtual void Draw() = 0; private; } ;

void Shape::Draw() {

cout << Abstract drawing mechanism!\ n ;

class Circle : public Shape {

public:

Circle(int radius):itsRadius(radius){ } virtual CircleOI }

long GetAreaO { return 3 * itsRadius * itsRadius; } long GetPerimO { return 9 * itsRadius; }



1 ... 124 125 126 [ 127 ] 128 129 130 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика