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

1 ... 117 118 119 [ 120 ] 121 122 123 ... 265


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

Дпсшииг 13.2. Проведение вниз

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

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

4: Sinclude <iostream h>

5: enum TYPE { HORSE, PEGASUS } ,

7- class Horse

B- {

9. public

10: virtual void Gallop(){ cout Galloping...\n ; } 11:

12: private-

13: int itsAge;

14: > ,

16: class Pegasus : public Horse

17: {

18: public:

20: virtual void FlyO { cout I can fly! I can fly! I can fly!\ n ; >

21: } ;

23. const int NumberHorse = 5,

24: int mainO

25: {

26 Horse* Ranch[NumberHorse];

27: Horse* pHorse:

28: int choice,1,

29: for (i=0; i<NumberHorse, i++)

30; {

31: cout (l)Horse (2)Pegasus: ;

32: cin choice;

33. if (choice == 2)

34: pHorse = new Pegasus:

35: else

36: pHorse = new Horse;

37: Ranch[i] = pHorse,

38: >

39: cout \ n ;

40: for (i=0; KNumberHorses:

41; {

42. Pegasus *pPeg = dynamic cast< Pegasus *> (Ranch[i]);



4.2 43 44 45 46 47 48 49 50

if (pPeg)

pPeg->Fly(); else

cout Just a horse\ n delete Ranch[i]:

>

return 0;

>

(l)Horse (2)Pegasus: 1

(l)Horse (2)Pegasus: 2

(l)Horse (2)Pegasus: 1

(l)Horse (2)Pegasus: 2

(l)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

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

Во время компиляции появляется сообщение об ошибке С4541: dynamic cast used on polymorphic type class Horse with/GR-; unpredictable behavior may result Как поступить!

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

1. Выберите в окне проекта команду ProjectoSettings.

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

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

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

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

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

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



ДоОавАБнив оОъвкта в два списка

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

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

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

Рвкомвнддвтся

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

Нв рвкомвнддвтся

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

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

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

Аосшинг 13.3. Миожесшвенное насжвдпванвв

2 3 4 5 6 7 8 9: 10: 11:

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

ftinclude <iostream.h>

class Horse {

public:

HorseO { cout Horse constructor... ; } virtual HorseO { cout Horse destructor., virtual void WhinnyO const { cout << Whinny!

; }



1 ... 117 118 119 [ 120 ] 121 122 123 ... 265

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