|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Механизм вызова виртуального метода
Работа виртуальных методов основана на косвенном вызове подпрограмм. При косвенном вызове команда вызова подпрограммы оперирует не адресом подпрограммы, а адресом места в памяти, где хранится адрес подпрограммы. Вы уже сталкивались с косвенным вызовом при использовании процедурных переменных. Процедурная переменная и была тем местом в памяти, где хранился адрес вызываемой подпрограммы. Для каждого виртуального метода тоже создается процедурная переменная, но ее наличие и использование скрыто от программиста. Все процедурные переменные с адресами виртуальных методов пронумерованы и хранятся в таблице, называемой таблицей виртуальных методов (VMT — от англ. Virtual Method Table). Такая таблица создается одна для каждого класса объектов, и все объекты этого класса хранят на нее ссылку.
Структура объекта в оперативной памяти:
В таблице виртуальных методов хранятся адреса всех виртуальных методов класса, независимо от того, унаследованы ли они от предка или перекрыты в данном классе.
Вызов виртуального метода осуществляется следующим образом: 1) Через объектную переменную выполняется обращение к занятому объектом блоку памяти; 2) Далее из этого блока извлекается адрес таблицы виртуальных методов (он записан в четырех первых байтах); 3) На основании порядкового номера виртуального метода извлекается адрес соответствующей подпрограммы; 4) Вызывается код, находящийся по этому адресу.
Покажем, как можно реализовать косвенный вызов виртуального метода ParseLine (он имеет нулевой номер в таблице виртуальных методов) обычными средствами процедурного программирования: type TVMT = array[0..9999] of Pointer; TParseLineFunc = function(Self: TTextReader; constLine: string): Integer; var Reader: TTextReader; // объектная переменная ObjectDataPtr: Pointer; // указатель на занимаемый объектом блок памяти VMTPtr: ^TVMT; // указатель на таблицу виртуальных методов MethodPtr: Pointer; // указатель на метод begin ... ObjectDataPtr:= Pointer(Reader); // обращение к данным объекта VMTPtr:= Pointer(ObjectDataPtr^); // извлечение адреса VMT MethodPtr:= VMTPtr^[0]; // извлечение адреса метода из VMT TParseLineFunc(MethodPtr)(Reader, S); // вызов метода ... end.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.) |