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

на главную

Жанры

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

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

Шрифт:

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

Анализ: В строках 4—14 объявляется тип абстрактных данных Mammal с двумя чистыми виртуальными методами Speak и Move. От класса Mammal производятся подклассы Dog, Cat и Horse, в каждом из которых замещаются соответствующим образом функции Speak и Move.

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

животного, адрес которого присваивается в строках 54—56 указателю ptr.

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

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

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

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

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

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

2:

3: #include <iostream.h>

4:

5: class Dog

6: {

7: public:

8: void Speakconst { cout << "Woof!\n"; }

9: void Move const { cout << "Walking to heel...\n"; }

10: void Eat const { cout << "Gobbling food...\n"; }

11: void Growl const { cout << "Grrrrr\n"; }

12: void Whimper const { cout << "Whining noises...\n"; }

13: void RollOver const { cout << "Rolling over...\n"; }

14: void PlayDead const { cout << "Is this the end of Little Caesar?\n";

15: };

16:

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

18: int main

19: {

20: const int MaxFuncs = 7;

21: PDF DogFunctions[MaxFuncs] =

22: { Dog::Speak,

23: Dog::Move,

24: Dog::Eat,

25: Dog::Growl,

26: Dog::Whimper,

27: Dog::RollOver,

28: Dog::PlayDead };

29:

30: Dog* pDog =0;

31: int Method;

32: bool fQuit = false;

33:

34: while (!fQuit)

35: {

36: cout << "(0)Quit (1)Speak (2)Move (3)Eat (4)Growl";

37: cout << " (5)Whimper (6)Roll Over (7)Play Dead: ";

38: cin >> Method;

39: if (Method == 0)

40: {

41: fQuit = true;

42: }

43: else

44: {

45: pDog = new Dog;

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

47: delete pDog;

48: }

49: }

50: return 0;

51: }

Результат:

(0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll 0ver (7)Play

Dead: 1

Woof!

(0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll 0ver (7)Play

Dead: 4

Grrr

(0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll 0ver (7)Play

Dead: 7

Is this the end of Little Caesar?

(0)Quit (1)Speak (2)Move (3)Eat (4)Growl (5)Whimper (6)Roll 0ver (7)Play

Dead: 0

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

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

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

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

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

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

Не рекомендуется:Не злоупотребляйте созданием указателей на функции-члены, если беэ них можно обойтись.

Резюме

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

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

Ведьма

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.54
рейтинг книги
Ведьма

Неудержимый. Книга IX

Боярский Андрей
9. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга IX

Играть, чтобы жить. Книга 1. Срыв

Рус Дмитрий
1. Играть, чтобы жить
Фантастика:
фэнтези
киберпанк
рпг
попаданцы
9.31
рейтинг книги
Играть, чтобы жить. Книга 1. Срыв

Эфемер

Прокофьев Роман Юрьевич
7. Стеллар
Фантастика:
боевая фантастика
рпг
7.23
рейтинг книги
Эфемер

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

На границе империй. Том 2

INDIGO
2. Фортуна дама переменчивая
Фантастика:
космическая фантастика
7.35
рейтинг книги
На границе империй. Том 2

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Энфис 2

Кронос Александр
2. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 2

Наследник старого рода

Шелег Дмитрий Витальевич
1. Живой лёд
Фантастика:
фэнтези
8.19
рейтинг книги
Наследник старого рода

Совок 5

Агарев Вадим
5. Совок
Фантастика:
детективная фантастика
попаданцы
альтернативная история
6.20
рейтинг книги
Совок 5

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

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Мастер 6

Чащин Валерий
6. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 6

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот