Полиморфизм, понятие абстрактного класса. Дружественные связи. - Painted-Black/BMSTU-OOP GitHub Wiki

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

Для того, чтобы класс стал абстрактным, необходимо ввести в класс хотя бы одну чистую виртуальную функ- цию. Чистая виртуальная функция — это функция, после объявления которой добавлено выражение = 0.

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

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

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

Дружественные связи

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

Если необходимо, чтобы функция работала с объектами двух разных классов, например, функция будет рассматривать объекты двух классов как аргументы и обрабатывать их скрытые данные, то необходима friend-функция. Она будет иметь доступ к скрытым данным обоих объектов.

С одной стороны, дружественные функции повышают гибкость языка, но, с другой стороны, они не соответствуют принципу ограничения доступа к данным, который гласит, что только функции-члены могут иметь доступ к скрытым данным класса. Дружественная функция объявляется таковой в том классе, к данным которого она захочет впоследствии получить доступ. Таким образом, программист, не имеющий доступа к исходному коду класса, не может сде- лать функцию дружественной. В этом смысле целостность данных сохраняется. Но все равно такие функции принципиально нечистоплотны и потенциально могут привести к «spaghetti-code» (код со слишком большим числом передач управления), когда множество дружественных функций фактически стирают границы между классами.

Методы могут быть превращены в дружественные функции одновременно с определением всего класса как дружественного.

Правила:

  • Дружба не наследуется
  • Дружба не транзитивна