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

Значения строкового типа

Строка занимает столько байт, какова максимальная длина

строки, плюс один байт. Первый байт содержит текущую динамическую

длину строки, а последующие байты содержат символы строки. Бит

длины и символы рассматриваются, как значения без знака. Макси-

мальная длина строки - 255 символов, плюс байт длины

(string[255]).

Значения множественного типа

Множество - это массив бит, в котором каждый бит указывает,

является элемент принадлежащим множеству или нет. Максимальное

число элементов множества - 256, так что множество никогда не мо-

жет занимать более 32 байт. Число байт, занятых отдельным мно-

жеством, вычисляется, как:

ByteSize = (Max div 8) - (Min div 8) + 1

где Мin и Мах - нижняя и верхняя граница базового типа этого мно-

жества. Номер байта для конкретного элемента E вычисляется по

формуле:

ByteNumber = (E div 8) - (Min div 8)

а номер бита внутри этого байта по формуле:

BitNumber = E mod 8

где E обозначает порядковое значение элемента.

Значения типа массив

Массив хранится в виде непрерывной последовательности пере-

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

шими индексами хранятся в младших адресах памяти. Многомерный

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

рее.

Значения типа запись

Поля записи хранятся, как непрерывная последовательность пе-

ременных. Первое поле хранится в младших адресах памяти. Если в

записи содержатся различные части, то каждая часть начинается с

одного и того же адреса памяти.

Объектные типы

Внутренний формат данных объекта имеет сходство с внутренним

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

как непрерывная последовательность переменных. Любое поле, унас-

ледованное от родительского (порождающего) типа, записывается пе-

ред новыми полями, определенными в дочернем (порожденном) типе.

Если объектный тип определяет виртуальные методы, конструк-

тор или деструктор, то компилятор размещает в объектном типе до-

полнительное поле данных. Это 16-битовое поле, называемое полем

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

смещения таблицы виртуальных методов в сегменте данных. Поле таб-

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

полей объектного типа. Если объектный тип наследует виртуальные

методы, конструкторы или деструкторы (сборщики мусора), то он

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

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

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

объекта осуществляется конструктором (или конструкторами) объект-

ного типа. Программа никогда не инициализирует поле таблицы вир-

туальных методов явно и не имеет к нему доступа.

Следующие примеры иллюстрируют внутренние форматы данных

объектных типов.

type

PLocation = ^TLocation;

TLocation = object

X,Y: integer;

procedure Init(PX, PY: Integer);

function GetX: Integer;

function GetY: Integer;

end;

PPoint = ^TPoint;

TPoint = object(TLocation)

Color: Integer;

constructor Init(PX, PY, PColor: Integer);

destructor Done; virtual;

procedure Show; virtual;

procedure Hide; virtual;

procedure MoveTo(PX, PY: I+nteger); virtual;

end;

PCircle = ^TCircle;

TCircle = object(TPoint)

Radius: Integer;

constructor Init(PX, PY, PColor, PRadius: Integer);

procedure Show; virtual;

procedure Hide; virtual;

procedure Fill; virtual;

end;

Рисунок 21.8 показывает размещение экземпляров типов

TLocation, TPoint и TCircle: каждый прямоугольник соответствует

одному слову памяти.

TLocation TPoint TCircle

----------- ------------ ------------

¦ X ¦ ¦ X ¦ ¦ X ¦

+----------+ +-----------+ +-----------+

¦ Y ¦ ¦ Y ¦ ¦ Y ¦

L----------- +-----------+ +-----------+

¦ Color ¦ ¦ Color ¦

+-----------+ +-----------+

¦ VMT ¦ ¦ VMT ¦

L------------ +-----------+

¦ Radius ¦

L------------

Рис. 21.8 Схема экземпляров типов TLocation, TPoint и

TCircle.

Так как TPoint является первым типом в иерархии, который

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

размещается сразу после поля Color.

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

Каждый объектный тип, содержащий или наследующий виртуальные

методы, конструкторы или деструкторы, имеет связанную с ним таб-

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

часть сегмента данных программы. Для каждого объектного типа (но

не для каждого экземпляра) имеется только одна таблица виртуаль-

ных методов, однако два различных объектных типа никогда не раз-

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

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

автоматически компилятором, и программа никогда не манипулирует

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

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

с помощью конструкторов программа никогда не работает с этими

указателями непосредственно.

Первое слово таблицы виртуальных методов содержит размер

экземпляров соответствующего объектного типа. Эта информация ис-

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

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

ширенного синтаксиса стандартных процедур New и Dispose.

Второе слово таблицы виртуальных методов содержит отрица-

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

информация используется ратификационным (т.е. подтверждающим

действительность) механизмом вызова виртуального метода для выяв-

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

выполняться конструктор) и для проверки согласованности таблицы

виртуальных методов. Когда разрешена ратификация виртуального вы-

зова (с помощью директивы {$R+} компилятора, которая расширена и

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

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

ред каждым вызовом виртуального метода. Программа ратификации

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

виртуальных методов не равно нулю и что сумма первого и второго

слов равна нулю. Если любая из проверок неудачна, то генерируется

ошибка 210 исполняющей системы Borland Pascal.

Разрешение проверок границ диапазонов и проверок вызовов

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

несколько больше, поэтому используйте {$R+} только во время от-

ладки и переключите эту директиву в состояние {$R-} в окончатель-

ной версии программы.

Наконец, начиная со смещения 4 таблицы виртуальных методов

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

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

содержит адрес точки входа соответствующего виртуального метода.

На Рис. 21.9 показано размещение таблиц виртуальных методов

типов Point и Circle (тип Location не имеет таблицы виртуальных

методов, т.к. не содержит в себе виртуальных методов, конструкто-

ров и деструкторов): каждый маленький прямоугольник соответствует

одному слову памяти, а каждый большой прямоугольник - двум словам

памяти.

Point VMT Circle VMT

---------------- -----------------

¦ 8 ¦ ¦ 8 ¦

+---------------+ +----------------+

¦ -8 ¦ ¦ -8 ¦

+---------------+ +----------------+

¦ 0 ¦ ¦ 0 ¦

+---------------+ +----------------+

¦ 0 ¦ ¦ 0 ¦

+---------------+ +----------------+

¦ ¦ ¦ ¦

¦ @TPoint.Done ¦ ¦ @TPoint.Done ¦

¦ ¦ ¦ ¦

+---------------+ +----------------+

¦ ¦ ¦ ¦

¦ @TPoint.Show ¦ ¦ @TCircle.Show ¦

¦ ¦ ¦ ¦

+---------------+ +----------------+

¦ ¦ ¦ ¦

¦ @TPoint.Hide ¦ ¦ @TCircle.Hide ¦

¦ ¦ ¦ ¦

+---------------+ +----------------+

¦ ¦ ¦ ¦

¦ @TPoint.MoveTo¦ ¦ @TPoint.MoveTo ¦

¦ ¦ ¦ ¦

L---------------- +----------------+

¦ ¦

¦ @TCircle.Fill ¦

¦ ¦

L-----------------

Рис. 21.9 Схемы таблиц виртуальных методов для TPoint и

TCircle.

Обратите внимание на то, как TCircle наследует методы Done и

MoveTo типа TPoint и как он переопределяет Show и Hide.

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

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

методов объектного типа в инициализируемых экземплярах. Например,

если имеется экземпляр P типа TPoint и экземпляр C типа TCircle,

то вызов P.Init будет автоматически записывать смещение таблицы

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

дов экземпляра P, а вызов C.Init точно так же запишет смещение

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

ных методов экземпляра C. Эта автоматическая инициализация явля-

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

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

альных методов также будет установлено. Таким образом, при воз-

никновении необходимости, конструктор может выполнить вызов вир-

туального метода.

Таблица динамических методов

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

каждого описанного в объектном типе виртуального метода и его

предков четырехбайтовую запись. В тех случаях, когда в порождаю-

щих типах (предках) определяется большее число виртуальных мето-

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

достаточно большой объем памяти, особенно если создается много

производных типов. Хотя в производных типах могут переопределять-

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

методов каждого производного типа содержит указатели метода для

всех наследуемых виртуальных методов, даже если они не изменя-

лись.

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

тиву. В Borland Pascal имеется формат таблицы методов и новый

способ диспетчеризации методов с поздним связыванием. Вместо ко-

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

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

рые были в объектном типе переопределены. Если в наследующих ти-

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

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

зует меньшее пространство, чем формат таблицы виртуальных мето-

дов.

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

два объектных типа:

type

TBase = object

X: Integer;

constructor Init;

destructor Done; virtual;

procedure P10; virtual 10;

procedure P20; virtual 20;

procedure P30; virtual 30;

procedure P30; virtual 30;

end;

type

TDerived = object(TBase)

Y: Integer;

constructor Init;

destructor Done; virtual;

procedure P10; virtual 10;

procedure P30; virtual 30;

procedure P50; virtual 50;

end;

На Рис. 21.10 и 21.11 показаны схемы таблицы виртуальных ме-

тодов и таблицы динамических методов для TBase и TDerived. Каждая

ячейка соответствует слову памяти, а каждая большая ячейка - двум

словам памяти.

ТВМ TBase ТДМ TBase

------------------- -------------------

¦ 4 ¦ ¦ 0 ¦

+------------------+ +------------------+

¦ -4 ¦ ¦ индекс в кэш ¦

+------------------+ +------------------+

¦ Смещ. ТДМ TBase ¦ ¦ смещение записи ¦

+------------------+ +------------------+

¦ 0 ¦ ¦ 4 ¦

+------------------+ +------------------+

¦ ¦ ¦ 10 ¦

¦ @TBase.Done ¦ +------------------+

¦ ¦ ¦ 20 ¦

L------------------- +------------------+

¦ 30 ¦

+------------------+

¦ 40 ¦

+------------------+

¦ ¦

¦ @TBase.P10 ¦

¦ ¦

+------------------+

¦ ¦

¦ @TBase.P20 ¦

¦ ¦

+------------------+

¦ ¦

¦ @TBase.P30 ¦

¦ ¦

+------------------+

¦ ¦

¦ @TBase.P40 ¦

¦ ¦

L-------------------

Рис. 21.10 Схемы таблицы виртуальных методов и таблицы дина-

мических методов для TBase.

Объектный тип имеет таблицу динамических методов только в

том случае, если в нем вводятся или переопределяются динамические

методы. Если объектный тип наследует динамические методы, но они

не переопределяются, и новые динамические методы не вводятся, то

он просто наследует таблицу динамических методов своего предка.

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

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

данных прикладной программы.

ТВМ TDerived ТДМ TDerived

-------------------- -------------------

¦ 6 ¦ ¦ Смещ. ТДМ TBase ¦

+-------------------+ +------------------+

¦ -6 ¦ ¦ индекс в кеше ¦

+-------------------+ +------------------+

¦ Смещ. ТДМ TDerived¦ ¦ смещение записи ¦

+-------------------+ +------------------+

¦ 0 ¦ ¦ 3 ¦

+-------------------+ +------------------+

¦ ¦ ¦ 10 ¦

¦ @TBase.Done ¦ +------------------+

¦ ¦ ¦ 30 ¦

L-------------------- +------------------+

¦ 50 ¦

+------------------+

¦ ¦

¦ @TDerived.P10 ¦

¦ ¦

+------------------+

¦ ¦

¦ @TDerived.P30 ¦

¦ ¦

+------------------+

¦ ¦

¦ @TDerived.T50 ¦

¦ ¦

L-------------------

Рис. 21.11. Схемы таблицы виртуальных методов и таблицы ди-

намических методов для TDerived.

Первое слово таблицы динамических методов содержит смещение

сегмента данных родительской таблицы динамических методов, или 0,

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

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

ется в кеш-буфере просмотра динамических методов (см. далее).

Четвертое слово таблицы динамических методов содержит счет-

чик записи таблицы динамических методов. Непосредственно за ним

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

кого метода, а затем список соответствующих указателей методов.

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

ких методов.

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