Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Либерти Джесс. Освой самостоятельно С++ за 21 день. - royallib.ru.rtf
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2.55 Mб
Скачать

Из каких частей состоят объекты, полученные в результате множественного наследования

Когда в памяти компьютера создается объект 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 Whinny()const { 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 Chirp()const { cout << "Chirp... "; }

32:       virtual void Fly()const

33:       {

34:          cout << "I can fly! I can fly! I can fly! ";

35:       }

36:       virtual COLOR GetColor()const { 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 Chirp()const { 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:

62:       long itsNumberBelievers;

63: };

64:

65: Pegasus::Pegasus(

66:    COLOR aColor,

67:    HANDS height,

68:    bool migrates,

69:    long NumBelieve):

70: Horse(aColor, height),

71: Bird(aColor, migrates),

72: itsNumberBelievers(NumBelieve)

73: {

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

75: }

76:

77: int main()

78: {

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

80:    pPeg->Fly();

81:    pPeg->Whinny();

82:    cout << "\nYour Pegasus is " << pPeg->GetHeight();

83:    cout << " hands tall and ";

84:    if (pPeg->GetMigration())

85:       cout << "it does migrate.";

86:    else

87:       cout << "it does not migrate.";

88:    cout << "\nA total of " << pPeg->GetNumberBelievers();

89:    cout << " people believe it exists.\n";

90:    delete pPeg;

91:    return 0;

92: }

Результат:

Horse constructor...

Bird constructor...

Pegasus constructor...

I can fly! I can fly! I can fly! Whinny!...

Your Pegasus is 5 hands tall and it does migrate.

A total of 10 people believe it exists.

Pegasus destructor...

Bird destructor...

Horse destructor...

Анализ: Класс Horse объявляется в строках 7—18. Конструктор этого класса принимает два параметра: один из них — это перечисление, объявленное в строке 5, а второй — новый тип, объявленный с помощью typedef в строке 4. Этот конструктор выполняется в строках 20—24. При этом инициализируется одна переменная-член и на экран выводится сообщение о работе конструктора класса Horse.

В строках 26—42 объявляется класс Bird, конструктор которого выполняется в строках 45—49. Конструктор этого класса также принимает два параметра. Обратите внимание на интересный факт: конструкторы обоих классов принимают перечисления цветов, с помощью которых в программе можно установить цвет лошади или цвет перьев у птицы. В результате, когда вы попытаетесь установить цвет Пегаса, может возникнуть проблема в работе программы, которая обсуждается несколько ниже.

Класс Pegasus объявляется в строках 50—63, а его конструктор — в строках 65—75. Инициализация объекта Pegasus выполняется тремя строками программы. Сначала конструктор класса Horse определяет цвет и рост. Затем конструктор класса Bird инициализируется цветом перьев и логической переменной. Наконец, происходит инициализация переменной-члена itsNumberBelievers, относящейся к классу Pegasus. После всех этих операций вызывается конструктор класса Pegasus.

В функции main() создается указатель на класс Pegasus, который используется для получения доступа к функциям-членам базовых объектов.