Понятие и назначение чистых виртуальных функций и абстрактных классов

Чисто виртуальная функция – это виртуальная функция, тело которой не определено. Она используется для того, чтобы отложить выбор реализации функции.

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

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

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

 

3.Понятие и виды полиморфизма в С++. Статический полиморфизм в С++: понятие, механизмы реализации.

 

Слово "полиморфизм" греческого происхождения и означает "имеющий много форм".

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

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

Статический полиморфизм реализуется в С++ с помощью механизмов переопределения и перегрузки.

Перегружать в С++ можно методы класса, обычные функции и операции. Перегружаемые функции и методы, в соответствии с общими правилами, могут отличаться типом возвращаемого параметра и сигнатурой ( количеством и типом передаваемых параметров).

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

 

Вопросы (часть 2)

 

1.Отношение между классами и объектами ассоциация: понятие, пример использования.

2.Отношения между классами: агрегация и композиция: понятие, пример использования.

3.Отношения между классами зависимость: понятие, пример использования.

Известны три основных типа отношений между классами.

Во-первых, это отношение "обобщение/специализация" (общее и частное), т.е. иерархия "является". Розы являются цветами, что значит: розы являются специализированным частным случаем, подклассом более общего класса "цветы".

Во-вторых, это отношение "целое/часть", т.е. иерархия "имеет". Например, лепестки являются частью цветов.

В-третьих, это семантические, смысловые отношения, ассоциации. Например, пчелы ассоциируются с цветами.

Языки программирования выработали несколько общих подходов к выражению таких отношений. В частности, большинство объектно-ориентированных языков непосредственно поддерживает следующие виды отношений:

– обобщение (наследование);

ассоциация;

агрегация (композиция);

– зависимость;

– инстанцирование. (шаблоны)

Ассоциация

} Пример. Класс Product– это то, что продали в некоторой сделке, а класс Sale– сама сделка, в которой продано несколько товаров.

Class Product; class Sale;

Class Product

{ Sale* lastSale;

. . .

};

Class Sale

{ Product** productSold;

. . .

};

Ассоциация – смысловая связь. По умолчанию, она не имеет направления и не объясняет, как классы общаются друг с другом. Мы можем только отметить семантическую зависимость, указав, какие роли играют классы друг для друга.

Так, ассоциация "Product – Sale" – двустороннее отношение: задавшись товаром, можно выйти на сделку, в которой он был продан, а пойдя от сделки, найти, что было продано.

Кратность (мощность) ассоциации – это количество ее участников. Различают три случая кратности ассоциации:

– один-к-одному;

– один-ко-многим;

– многие-ко-многим.

Рассмотренная в примере ассоциация имеет тип один-ко-многим: каждый экземпляр товара относится только к одной последней продаже, в то время как каждый экземпляр Sale может указывать на совокупность проданных товаров.

Отношение один-к-одному обозначает очень узкую ассоциацию. Например, в розничной системе продаж примером могла бы быть связь между классом "Продажа" и классом "Снятие денег с кредитной карточки": каждая продажа соответствует ровно одному снятию денег с данной кредитной карточки.

Отношение многие-ко-многим тоже нередки. Например, каждый объект класса "Покупатель" может инициировать сделку с несколькими объектами класса "Торговый агент", и каждый "Торговый агент" может взаимодействовать с несколькими объектами класса "Покупатель".

Класс может иметь ассоциацию с самим собой. Такая ассоциация называется рефлексивной.

Агрегация и композиция

} Пример. Класс объектов, управляющих температурой в теплице Controllerимеет атрибут h класса Heater (нагреватель).

Class Controller

{ Heater h;

. . .

};

    1. class Controller

{ Heater *h;

. . .

};

Агрегация является частным случаем ассоциации. Отношение агрегации между классами имеет непосредственное отношение к агрегации между их экземплярами.

Пример. Класс Controller является абстракцией объектов, управляющих температурой в теплице . Класс Controller – это целое, а экземпляр класса Heater (нагреватель) – одна из его частей. В рассмотренном случае мы имеем специальный случай агрегации – композицию.

Композиция – форма агрегирования, в которой целое владеет своими частями, имеющими одинаковое с ним время жизни. Части могут быть созданы после создания агрегата, но, будучи созданными, живут и умирают вместе с ним. Такие части могут также быть явно удалены перед уничтожением агрегата. В случае композитного агрегирования объект в любой момент времени может быть частью только одного композита.

С точки зрения реализации в языке С++ композиция может быть осуществлена включением атрибута-части в класс-агрегат по значению, как это сделано в примере 1. Менее обязывающим является включение по ссылке (пример 2) . В этом случае класс Controller по-прежнему означает целое, но его часть, экземпляр класса Heater, содержится в целом косвенно. Теперь объекты живут отдельно друг от друга: мы можем создавать и уничтожать экземпляры классов (объекты) независимо.

Агрегация является направленным отношением. Объект Heater входит в объект Controller, и не наоборот. Физическое вхождение одного в другое нельзя "зациклить", а указатели – можно (каждый из двух объектов может содержать указатель на другой).

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

Объекты-элементы создаются в том порядке, в котором они объявлены (а не в том порядке, в котором они перечислены в списке инициализаторов элементов конструктора), и до того, как будут созданы объекты включающего их класса.

Отношение зависимости (использования) между классами означает, что изменение в спецификации одного класса может повлиять на другой класс, который его использует, причем обратное в общем случае неверно. Можно сказать, что один из классов (клиент) пользуется услугами другого (сервера).

Один класс может использовать другой по-разному. В нашем примере это происходит при описании интерфейсной функции. Отношение использования также имеет место, если в реализации какой-либо операции происходит объявление локального объекта используемого класса.