Листинг. 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; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!