Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
HOR / TOTAL.DOC
Скачиваний:
8
Добавлен:
16.04.2013
Размер:
312.83 Кб
Скачать

5.2. Статические экземпляры классов.

Новая объектная модель, принятая в языке Object Pascal позволяет создавать только динамические экземпляры классов. Таким образом, нельзя объявить статический объект и использовать его в разных местах программы. Но спецификацияCORBA требует как минимум наличие для каждого классаClassX соответствующей ему константного экземпляра классаTypeCode, содержащего информацию об классе. В этом случае наличие постоянных статических экземпляров было бы гораздо производительнее с точки зрения использования этих объектов и проще в реализации с точки зрения разработчика системы.

Поэтому пришлось эмулировать статические объекты, основываясь на знании структуры представления объекта в памяти.

Представление объекта в памяти.

В памяти, на которую указывает переменная класса, первые четыре байта занимает указатель на таблицу виртуальных методов класса (Virtual Method Table - VMT). СтруктураVMT никакого значения не имеет и далее не рассматривается. После указателя наVMT, который заносится конструктором класса идут поля этого класса.

Предположим, у нас имеется класс ClassI, у которого есть единственное поле типаInteger:

type

ClassI = class

I: Integer;

constructor Create(AI: Integer);

destructor Destroy; override;

end;

constructorClassI.Create(AI: Integer);

begin

I := AI;

end;

destructorClassI.Destroy;

begin

I := 0;

end;

Тогда каждый объект этого класса занимает в памяти 8 байт, которые распределяются следующим образом:

Смещение

Размер поля

Значение поля

+0

4байта

Указатель на VMT

+4

4байта

I: Integer

Эмуляция с помощью структуры.

Для эмуляции статического экземпляра класса ClassI достаточно объявить статическую переменную - структуру с соответствующими полями. Отличительной особенность языкаObjectPascal является тот факт, что указатель наVMT имеет собственное представление, называемое ссылкой на класс9. Этот указатель можно получить просто используя имя класса, либо вызвав методClassType для конкретного экземпляра класса. Тогда можно определить следующую структуру:

type

ClassIClass = class of ClassI;

ClassIRecord = packed record

ClassInfo: ClassIClass;

I: Integer;

end;

Статический экземпляр этой структуры полностью соответствует представлению объекта класса ClassI в памяти и может быть использован следующим образом:

const

ARecord: ClassIRecord = (ClassInfo: ClassI; I: 8);

A: ClassI = @ARecord;

Теперь имеется переменная A10 классаClassI, которая указывает на статический экземпляр класса, при этом память, которую он занимает естественно не нужно удалять при завершении программы.

Вызов конструктора и деструктора.

Если имеется потребность в вызове конструктора - например в случае когда конструктор проводит какую-нибудь нетривиальную оптимизацию, отличную от простого копирования значений, то вместо статического определения полей структуры можно было бы совершенно нормально вызвать этот конструктор уже для имеющейся статической копии при инициализации программы, например в секции initialization11 соответствующего модуля:

const

ARecord: ClassIRecord = (ClassInfo: ClassI);

A: ClassI = @ARecord;

...

Соседние файлы в папке HOR