5.3. Техническая реализация виртуальных функций

Совокупность классов и подклассов, в которых определяется и переопределяется виртуальная функция, называется полиморфическим кластером этой виртуальной функции.

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

Чтобы добиться позднего связывания для объекта, его нужно объявить как указатель или ссылку на объект соответствующего класса. Для открытых производных классов (public) указатели и ссылки на объекты этих классов совместимы с указателями и ссылками на объекты базового класса.

Объект Си++ представляет собой непрерывный участок памяти. Указатель на такой объект содержит адрес этого участка. Вызов составной функции транслируется в обычный вызов функции с дополнительным аргументом, содержащим указатель на объект. Например:

class Name *object;

Object -> message(10);

преобразуется в

className_message(object, 10);

При создании объектов производных классов их поля сцепляются с полями родительских классов. Эту функцию выполняет компилятор.

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

Например, если класс Third имеет виртуальную функцию out(), то объявление объекта с помощью указателя и вызов

Third *c; c -> out();

компилируется в

(*(c -> virtual_table [2])) (c, );

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