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

1 ... 136 137 138 [ 139 ] 140 141 142 ... 265


40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

int mainO {

void (Mammal::*pFunc)() const =0;

Mammal* ptr =0;

int Animal;

int Method;

bool fQuit = false;

while (fQuit == false) {

cout (O)Quit (1)dog (2)cat (3)horse: cin >> Animal; switch (Animal)

case 1 case 2 case 3

ptr = new Dog; break;

ptr = new Cat; break; ptr = new Horse; break; default: fQuit = true; break;

if (fQuit) break;

cout (l)Speak (2)Move: ; cin Method; switch (Method) {

case 1: pFunc = Mammal::Speak; break; default: pFunc = Mammal::Move; break;

(ptr->*pFunc)(); delete ptr;

return 0;

f ;Ч (O)Quit (1)dog (2)cat (3)horse: 1

(l)Speak (2)Move: 1 Woof!

(O)Quit (1)dog (2)cat (3)horse: 2

(l)Speak (2)Move: 1

Meow!

(O)Quit (1)dog (2)cat (3)horse: 3

(l)Speak (2)Move: 2

Galloping

(O)Quit (1)dog (2)cat (3)horse: 0 f . В строках 4-14 объявляется тип абстрактных данных Mammal с двумя чис-

тыми виртуальными методами SpeakO и Move(). От класса Mammal производятся подклассы Dog, Cat и Horse, в каждом из которых замещаются соответствующим образом функции Speak() и Move().



в процессе выполнения тела функции mainO пользователю предлагается выбрать животное, после чего в области динамического обмена создается новый подкласс выбранного животного, адрес которого присваивается в строках 54-56 указателю pt г.

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

Наконец, строкой 71 для указателя ptr вызывается функция delete, которая очищает область памяти, занятую созданным ранее объектом. Заметьте, что нет смысла вызывать delete для pFunc, поскольку последний является указателем на код, а не на объект в области памяти. Хотя даже при попытке сделать это вы получите сообщение об ощибке компиляции.

Массивы указатвлви на функри-члвны

Аналогично указателям на обычные функции, указатели на функции-члены могут храниться в массиве. Для инициализации такого массива можно использовать адреса различных функций-членов. В таком случае, чтобы вызвать для объекта тот или иной метод, достаточно просто указать массив и индекс смешения. Именно такой подход применяется в листинге 14.11.

Листинг 14.11. Массив указатвлвО на функцин-чдвны

2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19 20 21 22

Листинг 14.11. Массивы указателей на функции-члены

ffinclude <iostream,h>

class Dog {

public:

void SpeakOconst { cout << Woof!\ n ; }

void MoveO const { cout << Walking to heel.,.\ n ; } void Eat() const { cout Gobbling food...\ n ; } void GrowlO const { cout Grrrrr\ n ; } void WhimperO const { cout << Whining noises...\ n ; } void RollOverO const { cout Rolling over...\ n ; } void PlayDeadO const { cout << Is this the end of Little Caesar\ n ; } } ;

typedef void (Dog::*PDF)()const ;

int mainO

const int MaxFuncs = 7; PDF DogFunctions[MaxFuncs] = { Dog::Speak,

:Move,

:Eat.

:Growl,

:Whimper,

:RollOver,

:PlayDead }



29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

Dog* pDog =0;

int Method;

bool fQuit = false;

while (!fQuit) {

cout (O)Quit (l)Speak (2)Move (3)Eat (4)Growr cout (5)Whimper (6)Roll Over (7)Play Dead; ; cin Method; if (Method == 0) {

fQuit = true;

else {

pDog = new Dog;

(pDog->*DogFunctions[Method-1])(); delete pDog;

return 0;

(O)Quit (l)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play

Dead; 1 Woof!

(O)Ouit (l)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead: 4 Grrr

(O)Quit (l)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead; 7

Is this the end of Little Caesar

(O)Ouit (l)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll Over (7)Play Dead; 0

В строках 5-15 создается класс Dog, содержащий семь функций-членов, характеризующихся одинаковыми сигнатурой и типом возврата. В строке 17 с помощью typedef объявляется тип PDF константных указателей на функции-члены Dog, которые не принимают и не возвращают никаких значений.

В строках 21-28 объявляется массив DogFunctions, предназначенный для хранения указателей на семь функций-членов.

В строках 36 и 37 пользователю предлагается выбрать метод. Выбор любого элемента, кроме Quit, приводит к созданию объекта класса Dog, после чего из массива вызывается соответствующий метод (строка 46). Ниже представлена еще одна строка, которая может немного смутить ващих знакомых программистов, работающих с С++;

(pDog->*-DogFunctions[Method-1])();

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



1 ... 136 137 138 [ 139 ] 140 141 142 ... 265

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