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

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

Жанры

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

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

Шрифт:

17: class Dog : public Mammal

18: {

19: public:

20: Dog { cout << "Dog Constructor...\n"; }

21: virtual ~Dog { cout << "Dog destructor...\n"; }

22: void WagTail { cout << "Wagging Tail...\n"; }

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

24: void Moveconst { cout << "Dog moves 5 steps...\n"; }

25: };

26:

27: int main

28: {

29:

30: Mammal *pDog = new Dog;

31: pDog->Move;

32: pDog->Speak;

33:

34: return 0;

35: }

Результат:

Mammal constructor...

Dog Constructor...

Mammal move one step

Woof!

Анализ:

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

В строке 30 создается указатель класса Mammal (pDog), но ему присваивается адрес нового объекта производного класса Dog. Поскольку собака является млекопитающим, это вполне логично. Данный указатель затем используется для вызова функции Move. Поскольку pDog известен компилятору как указатель класса Mammal, результат получается таким же, как при обычном вызове метода Move из объекта класса Mammal.

В строке 32 через указатель pDog делается обращение к методу Speak. В данном случае метод Speak объявлен как виртуальный, поэтому вызывается вариант функции Speak, замещенный в классе Dog.

Это кажется каким-то волшебством. Хотя компилятор знает, что указатель pDog принадлежит классу Mammal, тем не менее происходит вызов версии функции, объявленной в другом производном классе. Если создать массив указателей базового класса, каждый из которых указывал бы на объект своего производного класса, то, обращаясь попеременно к указателям данного массива, можно управлять выполнением всех вариантов замещенного метода. Эта идея реализована в листинге 11.9.

Листинг 11.9. Произвольное обращение к набору виртуальных функций 

1: //Листинг 11.9. Произвольное обращение к набору виртуальных функций

2:

3: #include <iostream.h>

4:

5: class Mammal

6: {

7: public:

8: Mammal:itsAge(1) { }

9: virtual ~Mammal { }

10: virtual void Speak const { cout << "Mammal speak!\n"; }

11: protected:

12: int itsAge;

13: };

14:

15: class Dog : public Mammal

16: {

17: public:

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

19: };

20:

21:

22: class Cat : public Mammal

23: {

24: public:

25: void Speakconst { cout << "Meow!\n"; }

26: };

27:

28:

29: class Horse : public Mammal

30: {

31: public:

32: void Speakconst { cout << "Whinny!\n"; }

33: };

34:

35: class Pig : public Mammal

36: {

37: public:

38: void Speakconst < cout << "Oink!\n"; }

39: };

40:

41: int main

42: {

43: Mammal* theArray[5];

44: Mammal* ptr;

45: int choice, i;

46: for ( i = 0; i<5; i++)

47: {

48: cout << "(1)dog (2)cat (3)horse (4)pig: ";

49: cin >> choice;

50: switch (choice)

51: {

52: case 1: ptr = new Dog;

53: break;

54: case 2; ptr = new Cat;

55: break;

56: case 3: ptr = new Horse;

57: break;

58: case 4: ptr = new Pig;

59: break;

60: default: ptr = new Mammal;

61: break;

62: }

63: theArray[i] = ptr;

64: }

65: for (i=0;i<5;i++)

66: theArray[i]->Speak;

67: return 0;

68: }

Результат:

(1)dog (2)cat (3)horse (4)pig: 1

(1)dog (2)cat (3)horse (4)pig: 2

(1)dog (2)cat (3)horse (4)pig: 3

(1)dog (2)cat (3)horse (4)pig; 4

(1)dog (2)cat (3)horse (4)pjg: 5

Woof!

Meow!

Whinny!

0ink!

Mammal speak!

Анализ:

Чтобы идея использования виртуальных функций была понятнее, в данной программе этот метод раскрыт наиболее явно и четко. Сначала определяется четыре класса — Dog, Cat, Horse и Pig, которые являются производными от базового класса Mammal.

В строке 10 объявляется виртуальная функция Speak класса Mammal. В строках 18, 25, 32 и 38 указанная функция замещается во всех соответствующих производных классах.

Пользователю предоставляется возможность выбрать объект любого производного класса, и в строках 46—64 создается и добавляется в массив указатель класса Mammal на вновь созданный объект.

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

Если функция-член была объявлена как виртуальная в базовом классе, следует ли повторно указывать виртуальность при объявлении этого метода в произ- водном классе?

Нет. Если метод уже был объявлен как виртуальный, то он будет оставаться таким, несмотря на замещение его в производном классе. В то же время для повышения читабельности программы имеет смысл (но не требуется) и в производных классах продолжать указывать на виртуальность данного метода с помощью ключевого слова virtual.

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

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

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

Попытка возврата. Тетралогия

Конюшевский Владислав Николаевич
Попытка возврата
Фантастика:
альтернативная история
9.26
рейтинг книги
Попытка возврата. Тетралогия

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

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Я – Стрела. Трилогия

Суббота Светлана
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Я – Стрела. Трилогия

Инженер Петра Великого

Гросов Виктор
1. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого

Колонист "Вано"

Сухов Лео
1. Антикризисный Актив
Фантастика:
героическая фантастика
попаданцы
7.17
рейтинг книги
Колонист Вано

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Возвышение Меркурия. Книга 8

Кронос Александр
8. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 8

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Девочка-яд

Коэн Даша
2. Молодые, горячие, влюбленные
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Девочка-яд

Идеальный мир для Лекаря 28

Сапфир Олег
28. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 28

Имя нам Легион. Том 9

Дорничев Дмитрий
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 9

Ермак. Регент

Валериев Игорь
10. Ермак
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ермак. Регент

Тигр под елку

Зайцева Мария
4. Наша
Любовные романы:
короткие любовные романы
5.00
рейтинг книги
Тигр под елку