- •Оглавление
- •1 Основные методы программирования. Лекция №2 5
- •2 Методы объектно-ориентированного программирования. Лекция №6. 15
- •2.4 Вопросы по теме 54
- •3 Объектно-ориентированное проектирование. Лекция №12 55
- •3.4 Вопросы по теме 74
- •Введение. Лекция №1.
- •1Основные методы программирования. Лекция №2
- •1.1Процедурное программирование Методы процедурного программирования
- •Этапы разработки программ. Лекция 3.
- •1.2Объектно-ориентированное программирование Лекция №4
- •Этапы разработки оо программ. Лекция №5
- •Конструкторы и деструкторы. Лекция №7.
- •Друзья класса
- •2.2Наследование. Лекция №8
- •Производный класс
- •Простое наследование
- •Множественное наследование. Лекция №9
- •Виртуальные базовые классы
- •2.3Полиморфизм. Лекция №10
- •Перегрузка операций
- •Преобразования типов, определяемые классом
- •Перегрузка функций.
- •Чистый полиморфизм
- •Виртуальные элементы-функции
- •Абстрактные классы. Лекция №11.
- •Параметрический полиморфизм
- •Шаблоны функций
- •Шаблоны классов
- •2.4Вопросы по теме
- •3Объектно-ориентированное проектирование. Лекция №12
- •3.1Концепция объектно-ориентированного проектирования
- •3.2Проектирование структурной схемы программы Составление начальной иерархии и структуры классов
- •Реорганизация иерархии и структуры классов
- •Организационная структура программы
- •3.3Проектирование файлов интерфейсов классов. Лекция № 13. Файл интерфейса базового класса
- •Файлы интерфейсов производных классов
- •Файл управления
- •3.4Вопросы по теме
- •Общие моменты разработки программы на основе объектно-ориентированного подхода
- •Приложение а
Множественное наследование. Лекция №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.
Для устранения этих недостатков имеется механизм виртуальных базовых классов.