Полиморфизм
В полиморфизме можно выделить два аспекта.
Полиморфизм метода
Под полиморфизмом метода можно понимать выполнение одного и того же метода различным способом для объектов разных классов в иерархии. Обеспечивается эта возможность за счет динамического связывания, которое реализуется с помощью виртуальных функций. Класс, содержащий виртуальные функции называется полиморфным. Синтаксически виртуальные функции определяются со словом virtualперед заголовком функции в описании класса.
Для полиморфного класса компилятор в случае создания объекта класса в программе автоматически гарнирует таблицу виртуальных функций vtableсодержащую список адресов всех виртуальных функций класса. Таблица генерируется одна на класс, не зависимо от количества объектов создаваемых в программе. У каждого объекта компилятором добавляется отдельные компонентные данные (поле) предназначенные для хранения адреса vtableсвоего класса, которая заполняется конструктором в момент создания объекта.
()
Вызов виртуальной функции осуществляется с помощью цепочки команд сгенерированных компилятором:
У объекта получить адрес vtable
В vtableполучить адрес вызываемой виртуальной функции
Перейти на точку входа в функцию и выполнить ее программный код.
Полиморфизм объектов
Под полиморфизмом объектов можно понимать возможность замены объекта одного класса объектом другого класса. Для того чтобы замена производилась корректно, необходимо:
Классы находились в одной иерархии наследования
Классы были полиморфны
Объекты создавались динамически
В отношении объектов c++ меняет правило совместимости типов: производный класс совместим по типу с любым из своих предков.
Агрегация
– это такое отношение между объектами, когда один класс, агрегат, включает в себя объекты других классов как свои составные части. Отношение агрегации можно определить как отношение целая часть. Отношение агрегации следует использовать, если имеет место:
Существенно ассиметричное отношение, целая часть
Операции над целым, переносимые на его части
Разделение частями свойств и поведения в целом
Отношение агрегации являться менее жестким и предполагает независимое существование составных частей агрегата, после его разрушения. Более жестким является отношение композиции: уничтожение композита приводит к уничтожению всех его составных частей. Формально в программе отношение агрегации представляется включением в агрегат указателей на его составные части. Композиция – включением компонентов объектного типа являющихся составными частями композита.
Часто схемы агрегации и наследования замещают, что позволяет улучшить восприятие объектной модели. В отношении агрегации часто возникает проблема владения или принадлежности объектов, т.е. компонент «должен знать» своего хозяина, т.е. агрегата.
Проблема может быть решена двумя способами:
Включение в компонент указателя на предполагаемый агрегат. В этом случае при описании компонентов агрегат еще не известен (описание агрегата возможно только после описания всех его компонентов). Решение проблемы может заключаться во включении и компонентов и агрегата в одну иерархию наследования. Тогда в компонентах используется указатель на базовый для агрегата класс, который в дальнейшем будет получать значения адреса реального агрегата. Отдельные компоненты агрегата должны создаваться при создании агрегата ( чаще всего), т.е. в конструкторе агрегата, а значит каждый компонент должен получить в качестве параметра адрес своего агрегата. Но физически агрегат еще не существует (пишем конструктор) а потому адрес его не определен. Решение проблемы состоит в использовании this.
Второй способ состоит в построении между объектами отношений использования, программно отношение оформляется передачей указателя на агрегат в компонентные функции его составных частей алгоритм которых требует обращения к свойствам агрегата.
В качестве примера агрегации рассмотрим динамическую картинку дождь со снегом.
См приложение.
Второй способ установление обратной связи между … и самим агрегатом состоит построение отношения использования когда ссылка на агрегат передается в компонентную функцию как параметр:
См приложение
Абсткратные классы – чистые виртуальные функции, как правило помещаются в вершине иерархии, объединяют свойства и поведения общие для всех своих потомков. Не предназначен для создания объектов и используется для реализации полиморфизма объектов.
Компонентные функции абстрактного класса не предпологающие реализацию, объявляются как чистые виртуальные функции.
Virtual тип имя_функции (список_параметров) = 0;
Чистая виртуальная функция является признаком абстрактного класса и в коде не имеет реализации. Должна быть переопределена во всех потомках. Попытка создать объект абстрактного класса приводит к ошибке.