Практическое занятие 19. Динамический полиморфизм. Абстрактные классы

 

Виртуальные методы

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

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

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

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

Для каждого полиморфного класса (не объекта!) создается таблица виртуальных методов (VMT или vtbl), в которой для каждого виртуального метода записан адрес начала его кода в памяти. Каждый объект содержит скрытое дополнительное поле указателя ссылки (ссылки) на VM T (называется vptr), которое заполняется конструктором при создании объекта (для этого компилятор добавляет в конструктор соответствующие инструкции).

На этапе компиляции ссылки на виртуальные методы заменяются на обращения к VMT через vptr объекта, а на этапе выполнения в момент обращения к методу его адрес выбирается из соответствующей VMT.

 

Правила описания и использования виртуальных методов:

· Если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров (включая тип возвращаемого значения), автоматически становится виртуальным (даже описанный без virtual), а с отличающимся набором параметров – обычным.

· Виртуальные методы наследуются, т.е. переопределять их в производном классе требуется только при необходимости задать отличающиеся действия. Права доступа при переопределении изменить нельзя.

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

· Виртуальный метод не может объявляться с модификатором static, но может быть дружественной функцией.

· Конструкторы не могут быть виртуальными, а деструкторы могут.

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

 

Абстрактные классы

Чисто виртуальная функция – это виртуальная функция, не имеющая определения в базовом классе. Вместо тела метода используется чистый инициализатор (= 0). Для объявления чисто виртуальной функции используется следующая синтаксическая конструкция:

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: