Чтение онлайн

на главную - закладки

Жанры

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

85:

86: protected:

87: COLOR itsColor;

88: };

89:

90: int main

91: {

92: Animal *pAnimal=0;

93: int choice;

94: bool fQuit = false;

95:

96: while (1)

97: {

98: cout << "(1)Dog (2)Horse (3)Fish(0)Quit: ";

99: cin >> choice; 100:

101: switch (choice)

102: {

103: case 1: pAnimal = new Dog(5,Brown);

104: break;

105: case 2: pAnimal = new Horse(4,Black);

106: break;

107: case 3: pAnimal = new

108: break;

109: default: fQuit = true

110: break;

111: }

112: if (fQuit)

113: break;

114:

115: pAnimal->Speak;

116: pAnimal->Eat;

117: pAnimal->Reproduce;

118: pAnimal->Move;

119: pAnimal->Sleep;

120: delete pAnimal;

121: cout << "\n";

122: }

123: return 0;

124: }

Результат:

(1)Dog (2)Horse (3)Bird (0)Quit: 1

Animal constructor. . .

Mammal constructor...

Dog constructor...

Woof!...

Dog eating. . .

Dog reproducing....

Dog running...

Dog snoring...

Dog destructor...

Mammal destructor...

Animal destructor...

(1)Dog (2)Horse (3)Bird (0)Quit: 0

Анализ:

В строках 7—21 объявляется абстрактный тип данных Animal. Единственный метод этого класса, не являющийся чистой виртуальной функцией, это общий для объектов всех производных классов метод itsAge. Остальные пять методов — Sleep, Eat, Reproduce, Move и Speak — объявлены как чистые виртуальные функции.

Класс Mammal производится от Animal в строках 29—37 и не содержит никаких данных. В нем замещается функция Reproduce, чтобы задать способ размножения, общий для всех млекопитающих. Класс Fish производится непосредственно от класса Animal, поэтому функция Reproduce в нем замещается иначе, чем в классе Mammal (и это соответствует реальности).

Во всех других классах, производимых от класса Mammal, теперь нет необходимости замещать общий для всех метод Reproduce, хотя при желании это можно сделать для определенного класса, как, например, в нашей программе это было сделано в строке 83 для класса Dog. Все остальные чистые виртуальные функции были замещены в классах Fish, Horse и Dog, поэтому для каждого из них можно создавать соответствующие объекты.

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

При попытке создать объекты для классов абстрактных типов данных Animal или Mammal компилятор покажет сообщение об ошибке.

Когда следует использовать абстрактные типы данных

В одних примерах программ, рассмотренных нами ранее, класс Animal являлся абстрактным типом данных, в других — нет. В каких же случаях нужно объявлять класс как абстрактный тип данных?

Нет никаких правил, которые требовали бы

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

Если же вы хотите смоделировать виртуальную псарню, то теперь класс Dog будет абстрактным, от которого можно производить подклассы, представляющие разные породы собак. Количество уровней абстрактных классов следует выбирать в зависимости от того, насколько детально вы хотите смоделировать реальный объект или явление.

Рекомендуется:Используйте абстрактные типы данных для создания общего интерфейса для всех производных классов. Обязательно замещайте в производных классах все чистые виртуальные функции. Объявляйте все функции, которые нужно замещать в производных классах, как чистые виртуальные функции.

Не рекомендуется:Не пытайтесь создать объектабстрактного класса.

Логика использования абстрактных классов

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

Представим, что нужно создать класс Timer, который умеет отсчитывать секунды. Такой класс может иметь целочисленную переменную-член itsSeconds, а также метод, осуществляющий приращение переменной itsSeconds.

Теперь предположим, что программа должна отслеживать и сообщать о каждом изменении переменной itsSeconds. Первое решение, которое приходит на ум, — это добавить в класс Timer метод уведомления об изменении переменной-члена. Но логически это не совсем верно, так как программа уведомления может быть достаточно сложной и по сути своей не является логической частью программы отсчета времени.

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

Таким образом, лучшим решением будет создание абстрактного класса обозревателя Observer с чистой виртуальной функцией Update.

Теперь создадим второй абстрактный класс — Subject. Он содержит массив объектов класса Observer. Кроме того, в нем объявлены два дополнительных метода: Register, который регистрирует объекты класса Observer, и Notify, который отслеживает изменения указанной переменной.

Поделиться:
Популярные книги

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Барон Дубов 2

Карелин Сергей Витальевич
2. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 2

Хозяйка покинутой усадьбы

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка покинутой усадьбы

Страж Кодекса. Книга II

Романов Илья Николаевич
2. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга II

Город воров. Дороги Империи

Муравьёв Константин Николаевич
7. Пожиратель
Фантастика:
боевая фантастика
5.43
рейтинг книги
Город воров. Дороги Империи

Новик

Ланцов Михаил Алексеевич
2. Помещик
Фантастика:
альтернативная история
6.67
рейтинг книги
Новик

Гридень 2. Поиск пути

Гуров Валерий Александрович
2. Гридень
Детективы:
исторические детективы
5.00
рейтинг книги
Гридень 2. Поиск пути

Хозяйка усадьбы, или Графиня поневоле

Рамис Кира
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Хозяйка усадьбы, или Графиня поневоле

Газлайтер. Том 2

Володин Григорий
2. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 2

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6

Барин-Шабарин

Гуров Валерий Александрович
1. Барин-Шабарин
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Барин-Шабарин