Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Otvety_ekzamen_CPP.doc
Скачиваний:
3
Добавлен:
21.09.2019
Размер:
311.81 Кб
Скачать
  1. Полиморфизм и позднее связывание.

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

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

  1. для каждого полиморфного класса компилятор строит таблицу адресов виртуальных функций vtable;

  2. каждый объект полиморфного класса содержит скрытый указатель vptr на таблицу адресов виртуальных функций;

  3. компилятор автоматически вставляет в начало конструктора полиморфного класса фрагмент кода, который инициализирует vptr;

  4. при вызове виртуальной функции, её адрес извлекается из таблицы vtable, на которую указывает vptr объекта.

  1. Передача аргументов по умолчанию в виртуальные функции.

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

  1. Виртуальные деструкторы.

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

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

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

virtual имя_функции (параметры) = 0;

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

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

  2. абстрактный класс нельзя использовать в явном преобразовании типов;

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]