АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Представление интерфейса в памяти

Читайте также:
  1. VII. МИФЫ ПАМЯТИ И ЗАБВЕНИЯ
  2. Алгебраическое представление двоичных чисел
  3. Архитектуры процессоров по разделению памяти данных и команд (Архитектура фон Неймана, Гарвардская архитектура).
  4. Брэнд должен запечатлеться в памяти потребителя
  5. Ваше представление о себе
  6. Взаимодействие памяти и процессора.
  7. Виды модулей оперативной памяти
  8. Виды музыкальной памяти. Мнемонические процессы при запоминании нотного текста
  9. Возможность целенаправленного развития памяти в учебной деятельности
  10. Вопрос: Нарушения памяти при локальных поражениях мозга.
  11. Восстановление памяти прошлых жизней
  12. Все научные открытия, научные теории расширяют представление человечества, в т.ч. в философском смысле. Внесли свой вклад в теорию познания и принципы квантовой теории.


Интерфейс по сути выступает дополнительной таблицей виртуальных методов, ссылка на которую укладывается среди полей объекта (таблица методов интерфейса). В ней хранятся указатели на методы класса, реализующие методы интерфейса.

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

 

Intf := Obj; // где Intf: ITextReader иObj: TTextReader

 

К адресу объекта добавляется смещение до скрытого поля внутри объекта и этот результат заносится в интерфейсную переменную.

 

Механизм вызова метода объекта через интерфейс

Алгоритм вызова метода интерфейса такой же, как алгоритм вызова метода класса. Когда через интерфейсную переменную выполняется вызов метода, Intf.NextLine, реализуется следующий алгоритм:

1) из интерфейсной переменной извлекается адрес (по нему хранится адрес таблицы методов интерфейса);

2) по полученному адресу извлекается адрес таблицы методов интерфейса;

3) на основании порядкового номера метода в интерфейсе из таблицы извлекается адрес соответствующей подпрограммы;

4) вызывается код, находящийся по этому адресу. Этот код является переходником от метода интерфейса к методу объекта. Его задача – восстановить из ссылки на интерфейс значение указателя Self (путем вычитания заранее известного значения) и выполнить прямой переход на код метода класса.

 

Обычными средствами процедурного программирования этот алгоритм реализуется так:

Type

TMethodTable = array[0..9999] ofPointer;

TNextLineFunc = function(Self: ITextReader): Boolean;

Var

Intf: ITextReader; // интерфейсная переменна

IntfPtr: Pointer; // адрес внутри интерфейсной переменной

TablePtr: ^TMethodTable; // указатель на таблицу методов интерфейса

MethodPtr: Pointer; // указатель на метод

Begin

...

IntfPtr := Pointer(Intf); // 1) извлечение адреса из интерфейсной

Переменной

TablePtr := Pointer(IntfPtr^); // 2) извлечение адреса таблицы методов

Интерфейса

MethodPtr := TablePtr^[3]; // 3) извлечение адреса нужного метода из таблицы



TNextLineFunc(MethodPtr)(Intf); // 4) вызов метода через переходник

...

End.

Вызов метода через интерфейс в машинном коде выполняется весьма эффективно (всего несколько инструкций процессора), поэтому в подавляющем большинстве случаев потерями на вызов можно пренебречь.

Для доступа к объекту через интерфейс нужна интерфейсная переменная:

Var

Intf: ITextReader;

Интерфейсная переменная занимает в оперативной памяти четыре байта, хранит ссылку на интерфейс объекта и автоматически инициализируется значением nil. Перед использованием интерфейсную переменную инициализируют значением объектной переменной:

Var


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |


Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.004 сек.)