Объектно-ориентированное программирование на языке С++. Лясин Д.Н - 73 стр.

UptoLike

Составители: 

73
Указатель на таблицу виртуальных методов (vtbl)
Компонентные данные объекта
Адрес виртуальной функции 1 (&func1)
Адрес виртуальной функции 2 (&func2)
Адрес виртуальной функции n (&funcN)
Вызов виртуальной функции в тексте программы транслятор преобразует в
обращение к соответствующей строке таблицы виртуальных функций.
Предположим, что pObjэто указатель, в который записан адрес объекта,
структура которого отображена на рисунке 13. В таком случае вызов виртуальной
функции func2 для этого объекта вида
pObj->func2()
преобразуется транслятором в следующий вызов:
(*(pObj->vptr[1])) (pObj)
При таком
вызове функции нет жесткой привязки вызова к какой-то
конкретной реализации компонентной функции в одном из классов, как это
происходило при статическом связывании. Теперь будет вызываться та функция,
адрес которой записан в элемент с индексом 1 таблицы виртуальных функций
объекта. Позднее связывание обеспечивается тем, что заполнение таблицы
виртуальных функций объекта происходит
уже на этапе выполнения программы.
Это делает конструктор, занося в каждую строку таблицы адрес той реализации
виртуального метода, который правильно описывает поведение объекта.
Указатель на таблицу виртуальных функций обязательно включается в самый
"верхний" базовый фрагмент объекта производного класса. В таблицу указателей
включаются адреса функций-членов фрагмента самого "нижнего" уровня,
Рисунок 13. Структура объекта, использующего виртуальные функции
                Указатель на таблицу виртуальных методов (vtbl)
                Компонентные данные объекта


                Адрес виртуальной функции 1 (&func1)
                Адрес виртуальной функции 2 (&func2)
                …
                Адрес виртуальной функции n (&funcN)

      Рисунок 13. Структура объекта, использующего виртуальные функции

     Вызов виртуальной функции в тексте программы транслятор преобразует в
обращение   к     соответствующей    строке   таблицы   виртуальных   функций.
Предположим, что pObj – это указатель, в который записан адрес объекта,
структура которого отображена на рисунке 13. В таком случае вызов виртуальной
функции func2 для этого объекта вида
     pObj->func2()
преобразуется транслятором в следующий вызов:
     (*(pObj->vptr[1])) (pObj)
     При таком вызове функции нет жесткой привязки вызова к какой-то
конкретной реализации компонентной функции в одном из классов, как это
происходило при статическом связывании. Теперь будет вызываться та функция,
адрес которой записан в элемент с индексом 1 таблицы виртуальных функций
объекта. Позднее связывание обеспечивается тем, что заполнение таблицы
виртуальных функций объекта происходит уже на этапе выполнения программы.
Это делает конструктор, занося в каждую строку таблицы адрес той реализации
виртуального метода, который правильно описывает поведение объекта.
Указатель на таблицу виртуальных функций обязательно включается в самый
"верхний" базовый фрагмент объекта производного класса. В таблицу указателей
включаются адреса функций-членов фрагмента самого "нижнего" уровня,
                                        73