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

на главную

Жанры

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

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

Шрифт:

Обычно конструктор класса инициализирует только собственные переменные и переменные-члены базового класса. Из этого правила делается исключение, если используется виртуальное наследование. Переменные основного базового класса инициализируются конструкторами не следующих производных от него классов, а тех, которые являются последними в иерархии классов. Поэтому класс Animal инициализируется не конструкторами классов Horse и Bird, а конструктором класса Pegasus. Конструкторы классов Horse и Bird также содержат команды инициализации базового класса Animal,

но при создании объекта Pegasus эта инициализация перекрывается конструктором данного класса.

Листинг 13.6 представляет собой программный код из листинга 13.5, переписанный таким образом, чтобы можно было воспользоваться преимуществами виртуального наследования.

Листинг. 13.6. Пример использования виртуального наследования

1: // Листинг 13.6.

2: // Виртуальное наследование

3: #include <iostream.h>

4:

5: typedef int HANDS;

6: enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown } ;

7:

8: class Animal // общий базовый класс для двух производных классов horse и bird

9: {

10: public:

11: Animal(int);

12: virtual ~Animal { cout << "Animal destructor...\n"; }

13: virtual int GetAge const { return itsAge; }

14: virtual void SetAge(int age) { itsAge = age; )

15: private:

16: int itsAge;

17: };

18:

19: Animal::Animal(int age):

20: itsAge(age)

21: {

22: cout << "Animal constructor...\n";

23: }

24:

25: class Horse : virtual public Animal

26: {

27: public:

28: Horse(C0L0R color, HANDS height, int age);

29: virtual ^Horse { cout << "Horse destructor...\n"; }

30: virtual void Whinnyconst { cout << "Whinny!... "; }

31: virtual HANDS GetHeight const { return itsHeight; }

32: virtual COLOR GetColor const { return itsColor; }

33: protected:

34: HANDS itsHeight;

35: COLOR itsColor;

36: };

37:

38: Horse::Horse(C0L0R color, HANDS height, intage):

39: Animal(age),

40: itsColor(color),itsHeight(height)

41: {

42: cout << "Horse constructor...\n";

43: }

44:

45: class Bird : virtual public Animal

46: {

47: public:

48: Bird(COLOR color, bool migrates, int age);

49: virtual ~Bird { cout << "Bird destructor...\n"; }

50: virtual void Chirpconst { cout << "Chirp... "; }

51: virtual void Flyconst

52: { cout << "I can fly! I can fly! I can fly! "; }

53: virtual COLOR GetColorconst { return itsColor; }

54: virtual bool GetMigration const { return itsMigration; }

55: protected:

56: COLOR itsColor;

57: bool itsMigration;

58: };

59:

60: Bird;:Bird(COLOR color, bool migrates, int age):

61: Animal(age),

62: itsColor(color), itsMigration(migrates)

63: {

64: cout << "Bird constructor...\n";

65: }

66:

67: class Pegasus : public Horse, public Bird

68: {

69: public:

70: void Chirpconst { Whinny; }

71: Pegasus(COLOR, HANDS, bool, long, int);

72: virtual ~Pegasus { cout << "Pegasus destructor...\n";}

73: virtual long GetNumberBelievers const

74: { return itsNumberBelievers; }

75: virtual COLOR GetColorconst { return Horse::itsColor; }

76: private:

77: long itsNumberBelievers;

78: };

79:

80: Pegasus::Pegasus(

81: COLOR aColor,

82: HANDS heigbt,

83: bool migrates,

84: long NumBelieve,

85: int age):

86: Horse(aColor, height,age),

87: Bird(aColor, migrates,age),

88: Animal(age*2),

89: itsNumberBelievers(NumBelieve)

90: {

91: cout << "Pegasus constructor...\n";

92: }

93:

94: int main

95: {

96: Pegasus *pPeg = new Pegasus(Red, 5, true, 10, 2);

97: int age = pPeg->GetAge;

98: cout << "This pegasus is " << age << " years old.\n";

99: delete pPeg:

100: return 0;

101: }

Результат:

Animal constructor...

Horse constructor...

Bird constructor. . .

Pegasus constructor...

Tnis pegasus is 4 years old.

Pegasus destructor...

Bird destructor...

Horse destructor...

Animal destructor...

Анализ: В строке 25 класс Horse виртуально наследуется от класса Animal, а в строке 45 так же наследуется класс Bird. Обратите внимание, что конструкторы обоих классов по-прежнему инициализируют класс Animal. Но как только создается объект Pegasus, конструктор этого класса заново инициализирует класс Animal, отменяя прежние инициализации. Убедиться в этом вы можете по результату, выводимому программой на экран. При первой инициализации переменной itsAge присваивается значение 2, но конструктор класса Pegasus удваивает это значение. В результате строка 98 программы выводит на экран значение 4.

Проблемы с неопределенностью наследования метода в классе Pegasus больше не возникает, поскольку теперь метод GetAge наследуется непосредственно из класса Animal. В то же время при обращении к методу GetColor по-прежнему необходимо явно указывать базовый класс, так как этот метод объявлен в обоих классах, Horse и Bird.

Проблемы с множественным наследованием

Хотя множественное наследование дает ряд преимуществ по сравнение с одиночным, многие программисты с неохотой используют его. Основная проблема состоит в том, что многие компиляторы C++ все еще не поддерживают множественное наследование; это осложняет отладку программы, тем более что все возможности, реализуемые этим методом, можно получить и без него.

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

Бездомыш. Предземье

Рымин Андрей Олегович
3. К Вершине
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Бездомыш. Предземье

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

Правила Барби

Аллен Селина
4. Элита Нью-Йорка
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Правила Барби

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Идеальный мир для Социопата 13

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

Чемпион

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

Курсант: Назад в СССР 10

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

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Мастер 3

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

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

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

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

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

Рядовой. Назад в СССР. Книга 1

Гаусс Максим
1. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Рядовой. Назад в СССР. Книга 1

Черный Маг Императора 9

Герда Александр
9. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 9