Освой самостоятельно С++ за 21 день.
Шрифт:
Ranch[0]: Whinny!... Horse destructor...
Ranch[1]: Whinny!... Pegasus destructor... Bird destructor...
Horse destructor...
Aviary[0]: Chirp... I can fly! I can fly! I can fly! Bird destructor...
Aviary[1]: Whinny!... I can fly! I can fly! I can fly!
Pegasus destructor... Bird destructor... Horse destructor...
Анализ: В строках 6—14 объявляется класс Horse. Конструктор и деструктор выводят на экран сообщения о своей работе, а метод Whinny печатает Whinny! (И-го-го).
Класс Bird
Наконец, в строках 30-36 объявляется класс Pegasus. Он производится сразу от двух базовых классов — Bird и Horse. В классе замешается метод Chirp таким образом, что вызывается метод Whinny, который унаследован этим классом от класса Horse.
Создается два списка: Ranch (конюшня), который в строке 41 связывается с классом Horse, и Aviary (птичник), который в строке 42 связывается с классом Bird. В строках 46—55 в список Ranch добавляются два объекта — Horse и Pegasus. В строках 56—65 в список Aviary добавляются объекты Bird и Pegasus.
Вызовы виртуальных методов с помощью указателей классов Bird и Horse одинаково выполняются для объекта Pegasus. Например, в строке 78 метод Chirp вызывается последовательно для всех объектов, указатели на которые представлены в массиве Aviary. Поскольку этот метод объявлен в классе Bird как виртуальный, он правильно Выполняется для всех объектов списка.
По выводимым на экран строкам можно заключить, что при создании объекта Pegasus вызываются конструкторы всех трех классов — Bird, Horse и Pegasus, каждый из которых создает свою часть объекта. При удалении объекта также удаляются его части, относящиеся к классам Bird и Horse, для чего деструкторы в этих классах объявлены как виртуальные.
Объявление множественного наследования
Чтобы указать, что создаваемый объект наследует свойства более чем одного базового класса после имени создаваемого класса ставится двоеточие, вслед за которым через запятую перечислены имена всех базовых классов.
Пример 1:
class Pegasus : public Horse, public Bird
Пример 2:
class Schnoodle : public Schnauzer, public Poodle
Из каких частей состоят объекты, полученные в результате множественного наследования
Когда в памяти компьютера создается объект Pegasus, конструкторы обоих классов принимают участие в его построении, как показано на рис. 13.1.
Рис. 13.1. Объект, полученный в результате множественного наследования
В
случае использования множественного наследования возникает ряд непростых и весьма интересных вопросов. Например, что произойдет, если оба базовых класса будут иметь одно и то же имя либо содержать виртуальные функции или данные с одинаковыми именами? Как инициализируются конструкторы разных базовых классов? Что произойдет, если два базовых класса будут произведены от одного и того же родительского класса? Все эти вопросы будут рассмотрены в следующем разделе, после чего можно переходить к практическому использованию множественного наследования.Конструкторы классов, полученных в результате множественного наследования
Если класс Pegasus производится от двух базовых классов — Bird и Horse, а в каждом из них объявлены конструкторы со списками параметров, то класс Pegasus инициализирует эти конструкторы. Как это происходит, показано в листинге 13.4.
Листинг 13.4. Создание объектов при множественном наследовании
1: // Листинг 13.4.
2: // Создание обьектов при множественном наследовании
3: #include <iostream.h>
4: typedef int HANDS;
5: enum COLOR { Red, Green, Blue, Yellow, White, Black, Brown };
6:
7: class Horse
8: {
9: public:
10: Horse(COLOR color, HANDS height);
11: virtual ~Horse { cout << "Horse destructor...\n"; }
12: virtual void Whinnyconst { cout << "Whinny!... "; }
13: virtual HANDS GetHeight const { return itsHeight; }
14: virtual COLOR GetColor const { return itsColor; }
15: private:
16: HANDS itsHeight;
17: COLOR itsColor;
18: };
19:
20: Horse::Horse(COLOR color, HANDSheight):
21: itsColor(color),itsHeight(height)
22: {
23: cout << "Horse constructor...\n";
24: }
25:
26: class Bird
27: {
28: public:
29: Bird(COLOR color, bool migrates);
30: virtual ~Bird { cout << "Bird destructor...\n"; }
31: virtual void Chirpconst { cout << "Chirp... "; }
32: virtual void Flyconst
33: {
34: cout << "I can fly! I can fly! I can fly! ";
35: }
36: virtual COLOR GetColorconst { return itsColor; }
37: virtual bool GetMigration const { return itsMigration; }
38:
39: private:
40: COLOR itsColor;
41: bool itsMigration;
42: };
43:
44: Bird::Bird(COLOR color, bool migrates):
45: itsColor(color), itsMigration(migrates)
46: {
47: cout << "Bird constructor...\n";
48: }
49:
50: class Pegasus : public Horse, public Bird
51: {
52: public:
53: void Chirpconst { Whinny; }
54: Pegasus(COLOR, HANDS, bool,long);
55: ~Pegasus { cout << "Pegasus destructor...\n";}
56: virtual long GetNumberBelievers const
57: {
58: return itsNumberBelievers;
59: }
60:
61: private: