Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие-ООП - копия.doc
Скачиваний:
20
Добавлен:
17.08.2019
Размер:
907.78 Кб
Скачать

Множественное наследование. Лекция №9

Множественным наследованием называется наследование, когда производный класс имеет непосредственно более одного базового класса. Примером множественного наследования является схема, представленная на рис. 2.2.

Рис. 2.2. Схема множественного наследования

Пусть объявлен объект производного класса: cl3 obj3;. Он будет иметь в памяти три части:

  • элементы, унаследованные от cl1 (явное наследование);

  • элементы, унаследованные от cl2 (явное наследование);

  • собственные элементы класса cl3.

Доступ к элементам производного класса (собственным и наследуемым) аналогичен доступу при простом наследовании.

Неоднозначность доступа возникает в следующих случаях:

  • в производном классе и в одном из базовых классов имеются элементы с одинаковыми именами;

  • в базовых классах имеются элементы с одинаковыми именами.

Например, имеется элемент int tabn в классах cl1 и cl2.

Для разрешения неоднозначности, как и при простом наследовании, нужно использовать имя базового класса с операцией разрешения видимости (например, obj3.cl1::tabn=20;доступ к tabn в cl1).

Конструктор производного класса позволяет инициализировать наследуемые элементы базовых классов и собственные элементы, как и при простом наследовании. Тогда в списке инициализации конструктора производного класса должны быть явно указаны имена конструкторов базовых классов. Например, конструктор класса cl3 может иметь вид: cl3(): cl1(),cl2() {...} Порядок выполнения конструкторов следующий: сначала будут выполняться конструкторы базовых классов в порядке их задания, затем - производного класса.

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

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

Рассмотрим следующую схему иерархии классов (рис. 2.3)

Рис. 2.3. Пример множественного неявного наследования

Объект obj4 класса cl4 имеет в памяти следующие части:

  • элементы, унаследованные неявно от cl1 по левой ветви;

  • элементы, унаследованные явно от cl2;

  • элементы, унаследованные неявно от cl1 по правой ветви;

  • элементы, унаследованные явно от cl3;

  • собственные элементы класса cl4.

Как видно, объект класса cl4 содержит две части (копии) элементов класса cl1, унаследованных неявно по левой и по правой ветвям. Возникает неопределенность при доступе к наследуемым элементам класса cl1 внутри класса cl4 или через объект класса cl4. Например, доступ к элементу tabn класса cl1 с помощью выражения obj4.tabn не верен. Для устранения необходимо указать путь (ветвь) наследования, т.е. имя базового класса соответствующей ветви с операцией разрешения видимости. Например, для доступа к tabn, унаследованному по левой ветви, необходимо выражение obj4.cl2::tabn, аналогично по правой ветви - obj4.cl3::tabn.

Пусть в предыдущем примере необходимо иметь в производном классе еще одну, третью часть (копию) элементов класса cl1, унаследованных явно. По двум ветвям элементы класса cl1 наследуются неявно, а по третьей ветви - явно. Это явная неоднозначность.

Базовый класс может быть объявлен непосредственно в определении производного класса только1 раз. Нельзя объявлять явно cl1 в cl4, так как cl1 уже объявлен в cl4 неявно через cl2 и cl3.

Для устранения неоднозначности можно заменить явное наследование класса cl1 на неявное, добавив пустой (без элементов) класс cl5 между cl1 и cl4 (рис. 2.4)

Рис. 2.4. Пример устранения неоднозначности при наследовании

Тогда доступ к трем унаследованным частям класса cl1, например, к tabn с помощью объекта класса cl4 можно представить, как:

obj.cl2::tabn=10;//доступ к части, унаследованной через cl2

obj.cl3::tabn=20;//доступ к части, унаследованной через cl3

obj.cl5::tabn=30;//доступ к части, унаследованной через cl5

В некоторых задачах наличие нескольких копий базового класса в производном классе необходимо. Но если достаточно одной копии базового класса cl1 в классе cl4, то проявляются недостатки неоднозначности множественного наследования:

  • тратится дополнительная память на лишние копии класса cl1;

  • сохраняется неопределенность доступа к элементам класса cl1.

Для устранения этих недостатков имеется механизм виртуальных базовых классов.