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

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

Жанры

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

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

Шрифт:

57: }

58:

59: void ValueFunction (Mammal MammalValue)

60: {

61: MammalValue.Speak;

62: }

63:

64: void PtrFunction (Mammal * pMammal)

65: {

66: pMammal->Speak;

67: }

68:

69: void RefFunction (Mammal & rMammal)

70: {

71: rMammal.Speak;

72: }

Результат:

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

Woof

Woof

Mammal Speak!

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

Meow!

Meow!

Mammal Speak!

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

Анализ:

В строках 5—25 определяются классы Mammal, Dog и Cat. Затем объявляются три функции — PtrFunction, RefFunction и ValueFunction. Они принимают соответственно указатель класса Mammal, ссылку класса Mammal и объект класса Mammal. После чего выполняют одну и ту же операцию — вызывают метод Speak.

Пользователю предлагается выбрать объект класса Dog или класса Cat, после чего в строках 43—46 создается указатель соответствующего типа.

Судя по информации, выведенной программой на экран, пользователь первый раз выбрал объект класса Dog, который был создан в свободной области памяти 43-й строкой программы. Затем объект класса Dog передается в три функции с помощью указателя, с помощью ссылки и как значение.

В том случае, когда в функцию передавался адрес объекта с помощью указателя или ссылки, успешно выполнялась функция-член Dog->Speak. На экране компьютера дважды появилось сообщение, соответствующее выбранному пользователем объекту.

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

Те же действия и с тем же результатом были выполнены затем и для объекта класса Cat.

Виртуальные деструкторы

В том случае, когда ожидается указатель на объект базового класса, вполне допустима и часто используется на практике передача указателя на объект производного класса. Что произойдет при удалении указателя, ссылающегося на объект производного класса? Если деструктор будет объявлен как виртуальный, то все пройдет отлично — будет вызван деструктор соответствующего производного класса. Затем деструктор производного класса автоматически вызовет деструктор базового класса, и указанный объект будет удален целиком.

Отсюда следует правило: если в классе объявлены виртуальные

функции, то и деструктор должен быть виртуальным.

Виртуальный конструктор-копировщик

Конструкторы не могут быть виртуальными, из чего можно сделать вывод, что не может быть также виртуального конструктора-копировщика. Но иногда требуется, чтобы программа могла передать указатель на объект базового класса и правильно скопировать его в объект производного класса. Чтобы добиться этого, необходимо в базовом классе создать виртуальный метод Clone. Метод Clone должен создавать и возвращать копию объекта текущего класса.

Поскольку в производных классах метод Clone замещается, при вызове его создаются копии объектов, соответствующие выбранному классу. Программа, использующая этот метод, показана в листинге 11.11.

Листинг 11.11. Виртуальный конструктор-копировщик

1: //Листинг 11.11. Виртуальный конструктор-копировщик

2:

3: #include <iostream.h>

4:

5: class Mammal

6: {

7: public:

8: Mammal:itsAge(1) { cout << "Mammal constructor...\n"; }

9: virtual ^Mammal { cout << "Mammal destructor...\n"; }

10: Mammal (const Mammal & rhs);

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

12: virtual Mammal* Clone { return new Mammal(*this); }

13: int GetAgeconst { return itsAge; }

14: protected:

15: int itsAge;

16: };

17:

18: Mammal::Mammal (const Mammal & rhs):itsAge(rhs.GetAge)

19: {

20: cout << "Mammal Copy Constructor...\n";

21: }

22:

23: class Dog : public Mammal

24: {

25: public:

26: Dog { cout << "Dog constructor...\n"; }

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

28: Dog (const Dog & rhs);

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

30: virtual Mammal* Clone { return new Dog(*this); }

31: };

32:

33: Dog::Dog(const Dog & rhs):

34: Mammal(rhs)

35: {

36: cout << "Dog copy constructor...\n";

37: }

38:

39: class Cat : public Mammal

40: {

41: public:

42: Cat { cout << "Cat constructor,,,\n"; }

43: ~Cat { cout << "Cat destructor...\n"; }

44: Cat (const Cat &);

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

46: virtual Mammal* Clone { return new Cat(*this); }

47: };

48:

49: Cat::Cat(const Cat & rhs):

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

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

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

Воин-Врач

Дмитриев Олег
1. Воин-Врач
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
6.00
рейтинг книги
Воин-Врач

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Огненный князь 3

Машуков Тимур
3. Багряный восход
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Огненный князь 3

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

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

Долг

Кораблев Родион
7. Другая сторона
Фантастика:
боевая фантастика
5.56
рейтинг книги
Долг

Гримуар темного лорда IX

Грехов Тимофей
9. Гримуар темного лорда
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда IX

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

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

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

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

Идеальный мир для Демонолога 8

Сапфир Олег
8. Демонолог
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Демонолога 8

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

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

Росток

Ланцов Михаил Алексеевич
2. Хозяин дубравы
Фантастика:
попаданцы
альтернативная история
фэнтези
7.00
рейтинг книги
Росток

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Стражи душ

Кас Маркус
4. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Стражи душ