Листинг. 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 Whinny()const { 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 Chirp()const { cout << "Chirp... "; }

51: virtual void Fly()const

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

53: virtual COLOR GetColor()const { 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 Chirp()const { 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 GetColor()const { 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++ все еще не поддерживают множественное наследование; это осложняет отладку программы, тем более что все возможности, реализуемые этим методом, можно получить и без него.

Действительно, если вы решите использовать в своей программе множественное наследование, следует учесть, что с отладкой программы могут возникнуть проблемы и чрезмерное усложнение программы, связанное с использованием этого подхода, не всегда оправдывается полученным эффектом.

 


Дата добавления: 2019-02-12; просмотров: 218; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!