Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

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

Методы обработки сообщений | Понятие ссылки на метод объекта | Понятие события | Ошибки и исключительные ситуации | Классы исключительных ситуаций | В тот момент, когда управление передается на Except, в программе считается, что ошибка обработана. | Для возврата по try используется стек вызова процедур. | Приемы надежного программирования | Описание интерфейса | Механизм подсчета ссылок в интерфейсах |


Читайте также:
  1. Алгоритм освобождения памяти
  2. Алгоритмы распределения памяти.
  3. Архитектура видеосистемы ПК. Управления видеосистемой. Режимы. Структура видеопамяти
  4. Архитектура и принцип работы часов реального времени RTC и CMOS памяти. Возможности программирования
  5. АРХИТЕКТУРА СИСТЕМНОГО ИНТЕРФЕЙСА СОВРЕМЕННЫХ ПК. НАЗНАЧЕНИЕ КОМПОНЕНТОВ. РЕЖИМЫ ПЕРЕДАЧИ ИНФОРМАЦИИ ПО системными шинами.
  6. Блок памяти (БП);
  7. Взаимодействие программ в памяти


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

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

 

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

 

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

 

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

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

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

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

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

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

Obj: TTextReader; // объектная переменная

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

Begin

...

Intf:= Obj;

...

End;

После инициализации интерфейсную переменную Intf можно использовать для вызова методов объекта Obj:

Intf.Active:= True; // -> Obj.SetActive(True);

Через интерфейсную переменную доступны только те методы и свойства объекта, которые есть в интерфейсе:

Intf.Free; // Ошибка! У интерфейса ITextReadaer нет методаFree.

Obj.Free; // Метод Free можно вызвать только так.

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


Дата добавления: 2015-11-16; просмотров: 76 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Reader._AddRef| Применение интерфейса для доступа к объекту динамически-подключаемой библиотеки

mybiblioteka.su - 2015-2024 год. (0.006 сек.)