Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора к КПИЯП.docx
Скачиваний:
41
Добавлен:
25.02.2016
Размер:
135.65 Кб
Скачать

17.2 Множественное наследование

  В С++ существует возможность наследовать более одного класса в качестве базового. Такой механизм наследования называется множественным наследованием. При множественном наследовании объекты производных классов могут использовать данные и методы нескольких классов, а также в свою очередь быть базовыми классами для других.

 

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

  

 

class имя_порожденного_класса: список_базовых_классов

 {

         …

 }

 

 

 

Последовательность расположения непосредственных базовых классов в списке определяет очередность вызова конструкторов умолчания. Этот порядок влияет и на очередность вызова деструкторов при уничтожении этих объектов.

 

 

Листинг 17.1 Пример множественного наследования 1

 

 

    #include <iostream.h>

 class X {

 protected:

      int a;

public:

     void make_a (int i) {a=i;}

};

class Y {

 protected:

     int b;

public:

     void make_b (int i) {b=i;}

};

class Z  : public X, public Y {

int make_ab() { return a*b;}

};

int main ()

{

        Z i;

         i. make_a (10);

         i. make_b(12);

         cout <<   i. make_ab ();

return 0;

}

 

 Поскольку класс Z наследует оба класса X и Y, то он имеет доступ к публичным и защищенным членам обоих классов.

Ситуация становится более сложной, когда класс содержит конструктор.

 

 

Листинг 17.2 Пример множественного наследования 2

 

 

    #include <iostream.h>

class X {

protected:

     int a;

public:

X () {a=10; cout << “ Initializing X \n”;}

};

class Y {

 protected:

     int b;

public:

Y () {b=12; cout << “ Initializing Y\n”;}

};

class Z  : public X, public Y {

Z() { cout << “ Initializing Z\n”; }

int make_ab() { return a*b;}

};

int main ()

{                     Z i;

                          cout <<   i. make_ab ();

return 0;

}

Initializing X

InitializingY

Initializing Z

 

 

Конструкторы базовых классов вызываются  в том порядке, в котором они указаны в списке при объявлении класса Z. Деструкторы вызываются в обратном порядке (справа налево).

 

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

 

 

 

Порожденный_ конструктор (список_аргументов): базовый1 (список_аргументов), базовый2 (список_аргументов), …, базовыйn (список_аргументов){ …};

 

Здесь под  базовый1, …, базовыйn обозначены имена базовых классов, наследуемые производным классом.

 

 

Листинг 17.3 Пример множественного наследования 3

 

 

    #include <iostream.h>

class X {

protected:

     int a;

public:

X (int i) {a=i; }

};

class Y {

 protected:

     int b;

public:

Y (int i) {b=i; }

};

class Z  : public X, public Y {

Z(int x, int y): X(x), Y(y) { cout << “ Initializing Z\n”; }

int make_ab() { return a*b;}

};

int main ()

{

         Z i(10,20);

        cout <<   i. make_ab ();

return 0;

}

 

  Атрибуты наследования и их смысл тот же, что и при одиночном наследовании. Данная последовательность базовых классов определяет порядок вызова конструкторов базовых классов. При создании экземпляра производного класса в первую очередь вызовется конструктор базового класса, имя которого определено первым в списке наследуемых классов. Далее - по порядку. Последним вызовется конструктор производного класса. При уничтожении объекта производного класса деструкторы вызываются в обратном порядке вызовам конструкторов. Как и в случае одиночного наследования, если конструктор или конструкторы базового класса содержат как минимум один аргумент, то производный класс также должен содержать конструктор.

 

Одно и тоже имя класса не может входить боле одного раза в список баз при объявлении производного класса. Это означает, что в наборе непосредственных базовых классов, которые участвуют в формировании производного класса не должно встречаться повторяющихся элементов.