Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
BorlandPascal.doc
Скачиваний:
54
Добавлен:
17.03.2015
Размер:
2.83 Mб
Скачать

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

Для вызова виртуального метода компилятор генерирует код,

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

цы виртуальных методов объекта, и затем вызывает метод, используя

связанную с ним точку входа. Например, если дана переменная PP

типа Point, то вызов PP^.Show будет генерировать следующий код:

les di, PP ; загрузить PP в ES:DI

push es ; передать, как параметр Self

push di

mov di, es:[di + 6] ; извлечь смещение ТВМ из поля ТВМ

call DWORD PTR [di + 12] ; вызвать запись ТВМ для Show

Правила совместимости типов для объектных типов позволяют PP

указывать на Point и на TCircle или на любых других потомков

TPoint. И если вы просмотрите показанные здесь таблицы виртуаль-

ных методов, то вы увидите, что для типа TPoint точка входа со

смещением 12 в таблицы виртуальных методов указывает на

TPoint.Show. Таким образом, в зависимости от фактического во вре-

мя выполнения типа PP, инструкция CALL вызывает либо TPoint.Show,

либо TCircle.Show, либо метод любого другого потомка TPoint.

Если Show является статическим методом, то для вызова

PP.Show будет генерироваться следующий код:

les di, PP ; загрузить PP в ES:DI

push es ; передать, как параметр Self

push di

call TPoint.Show ; непосредственно вызвать TPonit.Show

В данном случае не имеет значения, на что указывает PP, и

код всегда будет вызывать метод TPoint.Show.

Вызовы динамических методов

Диспетчеризация вызова динамического метода несколько более

сложна и требует больше времени, чем диспетчеризация виртуального

метода. Вместо использования инструкции CALL для вызова через

указатель метода по статическому смещению в таблице виртуальных

методов, таблица динамических методов объектного типа и таблица

динамических методов его предка должны просматриваться в поиске

"самого верхнего" вхождения индекса конкретного динамического ме-

тода, а вызов затем должен выполняться через соответствующий ука-

затель метода. Этот процесс требует использования существенно

большего числа инструкций, которые можно записать, как "встроен-

ные" (inline), поэтому Турбо Паскаль обеспечивает подпрограмму

диспетчеризации, используемую при вызове динамического метода.

Если бы метод Show показанного выше типа TPoint

описывался как динамический метод (с индексом динамического

метода 200), то вызов PP^.Show, где PP имеет тип TPointPtr,

привел бы к генерации следующего кода:

les di,PP ; загрузка PP в ED:DI

push es ; передача, как параметра

; Self

push di

mow di,es:[di+6] ; извлечение смещения

; таблицы виртуальных методов

; из поля таблицы

; виртуальных методов

mov ax,200 ; загрузка в AX индекса

; динамического метода

call Dispatch ; вызов подпрограммы

; диспетчеризации

Диспетчер выбирает сначала смещение таблицы динамических ме-

тодов от таблицы виртуальных методов, на которое указывает ре-

гистр DI. Затем используется "индекс в кеше" - поле таблицы дина-

мических методов. Диспетчер проверяет, является ли индекс вызван-

ного динамического метода индексом того динамического метода, ко-

торый вызывался последним. Если это так, он немедленно передает

этому методу управление (путем перехода с помощью указателя мето-

да, записанного по смещению, заданному полем "смещение записи").

Если динамический индекс вызванного метода не совпадает с

тем, который записан в кеше, то диспетчер просматривает таблицу

динамических методов и родительскую таблицу динамических методов

(следуя по связям в таблице динамических методов), пока он не

найдет запись, с данным индексом динамического метода. Индекс и

смещение соответствующего указателя метода записываются затем в

поле таблицы динамических методов, а управление передается мето-

ду. Если по каким-либо причинам диспетчер не может найти запись с

данным индексом динамического метода, он завершает прикладную

программу с кодом ошибки этапа выполнения 210.

Вопреки кешированию и высокооптимизированной подпрограмме

диспетчеризации, диспетчеризация динамического метода может пот-

ребовать существенно больше времени, чем вызов виртуального мето-

да. Однако в тех случаях, когда сами действия, выполняемые дина-

мическим методом, требуют много времени, дополнительное прост-

ранство, сохраняемое таблицами динамических методов, может пере-

весить этот недостаток.

Соседние файлы в предмете Программирование на Pascal