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

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

Жанры

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

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

Шрифт:

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

Листинг 13.2. Приведение вниз

1: // Листинг 13 2 Использование оператора dynamic_cast

2: //

Использование rtti

3:

4: #include <iostream h>

5: enum TYPE { HORSE, PEGASUS };

6:

7: class Horse

8: {

9: public

10: virtual void Gallop{ cout << "Galloping...\n"; }

11:

12: private:

13: int itsAge;

14: };

15:

16: class Pegasus : public Horse

17: {

18: public:

19:

20: virtual void Fly { cout << "I can fly! I can fly! I can fly!\n"; }

21: };

22:

23: const mt NumberHorse = 5,

24: int main

25: {

26: Horse* Ranch[NumberHorse];

27: Horse* pHorse;

28: int choice,i,

29: for (i=0; KNumberHorse, i++)

30: {

31: cout << "(1)Horse (2)Pegasus: ";

32: cin >> choice;

33: if (choice == 2)

34: pHorse = new fegasus;

35: else

36: pHorse = new Horse;

37: Rancfi[i] = pHorse,

38: }

39: cout << "\n";

40: for (i=0; a<NumberHorses; i++)

41: {

42: Pegasus *pPeg = dynamic_cast< Pegasus *> (Ranch[i]);

43: if (pPeg)

43: pPeg->Fly;

44: else

45: cout << "Just a horse\n";

46:

47: delete Ranch[i];

48: }

49: return 0;

50: }

Результат:

(1)Horse (2)Pegasus: 1

(1)Horse (2)Pegasus: 2

(1)Horse (2)Pegasus: 1

(1)Horse (2)Pegasus: 2

(1)Horse (2)Pegasus: 1

Just a horse

I can fly! I can fly! I can fly!

Just a horse

I can fly! I can fly! I can fly!

Just a horse

Вопросы и ответы

Во время компиляции появляется сообщение об ошибке C4541: 'dynamic_cast' used on polymorphic type 'class Horse' with/GR-; unpredictable behavior may result

Как поступить?

Это сообщение MFC действительно может смутить начинающего программиста. Чтобы устранить ошибку, выполните ряд действий.

1. Выберите в окне проекта команду Project->Settings.

2. Перейдите к вкладке С/C++.

3. Выберите в раскрывающемся списке Category опцию C++ Language

4. Установите Enable Runtime Type Information (RTTI).

5. Повторно скомпилируйте весь проект.

Анализ: Этот пример программы также будет вполне работоспособным. Метод Fly не связан напрямую с классом Horse

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

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

Добавление объекта в два списка

Другая проблема состоит в том, что при объявлении Pegasus как объекта типа Horse становится невозможным добавить его в список объектов класса Bi rd. Приходилось то переносить функцию Fly вверх по иерархии классов, то выполнять приведение указателя, но так и не удалось в полной мере достичь необходимого функционирования программы.

Таким образом, придерживаясь только одиночного наследования, оказалось невозможным элегантно решить эту проблему. Можно перенести все три функции — Fly, Whinny и Gallop — в базовый класс Animal, общий для двух производных классов Bird и Horse. В результате вместо двух списков объектов для классов Bird и Horse получится один общий список объектов класса Animal. Недостаток метода состоит в том, что базовый класс принимает на себя слишком много функций.

В качестве альтернативы можно оставить методы там, где они есть, и заняться приведением типов объектов классов Horse, Bird и Pegasus, но результат в конечном итоге будет еще хуже!

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

Не рекомендуется:Не переносите вверх по иерархии классов интерфейсы производных классов.

Множественное наследование

Существует возможность производить новые классы более чем от одного базового класса. Такой процесс называется множественным наследованием. Чтобы произвести подобный класс, базовые классы в объявлении разделяются запятыми. В листинге 13.3 класс Pegasus объявлен таким образом, что наследует свойства двух базовых классов — Bird и Horse. Затем программа добавляет объект Pegasus в списки объектов обоих классов.

Листинг 13.3. Множественное наследование 

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

Генерал-адмирал. Тетралогия

Злотников Роман Валерьевич
Генерал-адмирал
Фантастика:
альтернативная история
8.71
рейтинг книги
Генерал-адмирал. Тетралогия

Боярышня Евдокия 4

Меллер Юлия Викторовна
4. Боярышня
Фантастика:
альтернативная история
фэнтези
5.00
рейтинг книги
Боярышня Евдокия 4

Светлая. Книга 2

Рут Наташа
2. Песни древа
Фантастика:
постапокалипсис
рпг
фэнтези
5.00
рейтинг книги
Светлая. Книга 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

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

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

Полковник Гуров. Компиляция (сборник)

Макеев Алексей Викторович
Полковник Гуров
Детективы:
криминальные детективы
шпионские детективы
полицейские детективы
боевики
крутой детектив
5.00
рейтинг книги
Полковник Гуров. Компиляция (сборник)

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья

Сумеречный стрелок 6

Карелин Сергей Витальевич
6. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 6

Черный дембель. Часть 2

Федин Андрей Анатольевич
2. Черный дембель
Фантастика:
попаданцы
альтернативная история
4.25
рейтинг книги
Черный дембель. Часть 2

(Не)зачёт, Дарья Сергеевна!

Рам Янка
8. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
(Не)зачёт, Дарья Сергеевна!

Дважды одаренный. Том II

Тарс Элиан
2. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Дважды одаренный. Том II

Держать удар

Иванов Дмитрий
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Держать удар

Дорогами алхимии

Видум Инди
2. Под знаком Песца
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Дорогами алхимии

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

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