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

на главную

Жанры

Освой самостоятельно С++ за 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. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Вперед в прошлое 6

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

Архил...? Книга 2

Кожевников Павел
2. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...? Книга 2

Чемпион

Демиров Леонид
3. Мания крафта
Фантастика:
фэнтези
рпг
5.38
рейтинг книги
Чемпион

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5

Я граф. Книга XII

Дрейк Сириус
12. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я граф. Книга XII

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Титан империи 3

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

Темный Охотник

Розальев Андрей
1. КО: Темный охотник
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Мастер Разума II

Кронос Александр
2. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.75
рейтинг книги
Мастер Разума II

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

Винокуров Юрий
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Кодекс Охотника. Книга VII

Большие дела

Ромов Дмитрий
7. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Большие дела

Я тебя верну

Вечная Ольга
2. Сага о подсолнухах
Любовные романы:
современные любовные романы
эро литература
5.50
рейтинг книги
Я тебя верну