- •Часть I. Язык Borland Pascal Глава 1. Что такое программа Borland Pascal?
- •Программа Borland Pascal
- •Процедуры и функции
- •Операторы
- •Выражения
- •Лексемы
- •Типы, переменные, константы и типизированные константы
- •Компоновка частей
- •Синтаксические диаграммы
- •Глава 2.Лексемы
- •Специальные символы
- •Зарезервированные слова и стандартные директивы Borland Pascal
- •Идентификаторы
- •Строки символов
- •Комментарии
- •Строки программы
- •Глава 3. Константы
- •Глава 4. Типы
- •Простые типы
- •Порядковые типы
- •Целочисленные типы
- •Булевские типы
- •Символьный тип (char)
- •Перечислимые типы
- •Отрезки типа
- •Вещественные типы
- •Программная поддержка чисел с плавающей точкой
- •Аппаратная поддержка чисел с плавающей точкой
- •Строковые типы
- •Структурные типы
- •Типы массив
- •Типы запись
- •Объектные типы
- •Компоненты и область действия
- •Виртуальные методы
- •Динамические методы
- •Создание экземпляров объектов
- •Активизация методов
- •Активизация уточненных методов
- •Множественные типы
- •Файловые типы
- •Ссылочные типы
- •Тип Pointer
- •Тип pChar
- •Процедурные типы
- •Процедурные значения
- •Совместимость типов
- •Тождественные и совместимые типы
- •Тождественность типов
- •Совместимость типов
- •Совместимость по присваиванию
- •Раздел описания типов
- •Глава 5. Переменные и типизированные константы Описания переменных
- •Сегмент данных
- •Сегмент стека
- •Абсолютные переменные
- •Ссылки на переменные
- •Квалификаторы
- •Массивы, строки и индексы
- •Записи и десигнаторы полей
- •Десигнаторы компонентов объекта
- •Переменные-указатели и динамические переменные
- •Приведение типов переменных
- •Типизированные константы
- •Константы простого типа
- •Константы строкового типа
- •Константы структурного типа
- •Константы типа массив
- •Константы типа запись
- •Константы объектного типа
- •Константы множественного типа
- •Константы ссылочного типа
- •Константы процедурного типа
- •Глава 6. Выражения
- •Синтаксис выражений
- •Операции
- •Арифметические операции
- •Унарные арифметические операции
- •Логические операции
- •Булевские операции
- •Операция со строками
- •Операции над символьными указателями
- •Операции над множествами
- •Операции отношения
- •Сравнение простых типов
- •Сравнение строк
- •Сравнение упакованных строк
- •Сравнение указателей
- •Сравнение символьных указателей
- •Сравнение множеств
- •Проверка на принадлежность к множеству
- •Операция @
- •Использование операции @ для переменной
- •Использование операции @ для процедуры или функции или метода
- •Вызовы функции
- •Описатели множества
- •Приведение типа значений
- •Процедурные типы в выражениях
- •Глава 7. Операторы
- •Простые операторым
- •Оператор присваивания
- •Операторы процедуры
- •Операторы перехода
- •Структурные операторы
- •Составные операторы
- •Условные операторы
- •Оператор условия (if)
- •Оператор варианта (case)
- •Оператор цикла
- •Оператор цикла с постусловием (repeat)
- •Операторы цикла с предусловием (while)
- •Операторы цикла с параметром (for)
- •Оператор with
- •Глава 8. Блоки, локальность и область действия
- •Синтаксис
- •Правила для области действия
- •Область действия для блока
- •Область действия записи
- •Область действия объекта
- •Область действия модуля
- •Глава 9. Процедуры и функции
- •Описания near и far
- •Описания export
- •Описания interrupt
- •Описание forward
- •Описания external
- •Описания assembler
- •Описания inline
- •Описания функций
- •Описания методов
- •Конструкторы и деструкторы
- •Восстановление ошибок конструктора
- •Параметры
- •Параметры-значения
- •Параметры-константы
- •Параметры-переменные
- •Нетипизированные параметры
- •Открытые параметры
- •Открытые строковые параметры
- •Открытые параметры-массивы
- •Динамические переменные объектного типа
- •Процедурные переменные
- •Параметры процедурного типа
- •Глава 10. Программы и модули Синтаксис программ
- •Заголовок программы
- •Оператор uses
- •Синтаксис модулей
- •Заголовок модуля
- •Интерфейсная секция
- •Секция реализации
- •Секция инициализации
- •Косвенные ссылки на модули
- •Перекрестные ссылки на модули
- •Совместное использование описаний
- •Глава 11. Динамически компонуемые библиотеки
- •Что такое dll?
- •Использование dll
- •Модули импорта
- •Статический и динамический импорт
- •Написание dll
- •Директива процедуры export
- •Оператор exports
- •Код инициализации библиотеки
- •Замечания по программированию библиотек
- •Глобальные переменные в dll
- •Глобальные переменные и файлы в dll
- •Dll и модуль System
- •Ошибки этапа выполнения в dll
- •Dll и сегменты стека
- •Создание совместно используемых dll
- •Часть II. Глава 12. Библиотеки исполняющей системы
- •Модули Borland Pascal
- •Модуль System
- •Модуль Dos и WinDos
- •Модуль Crt
- •Модуль WinCrt
- •Модули Turbo3 и Graph3
- •Модули WinTypes и WinProcs
- •Модуль Win31
- •Модуль WinApi
- •Модули, поддерживающие Windows 3.1
- •Глава 13. Стандартные процедуры и функции
- •Процедуры управления работой программы
- •Функции преобразования
- •Арифметические функции
- •Порядковые процедуры и функции
- •Строковые процедуры и функции
- •Процедуры и функции динамического распределения памяти
- •Функции для работы с указателями и адресами
- •Прочие процедуры и функции
- •Предописанные переменные
- •Глава 14. Ввод и вывод
- •Файловый ввод-вывод
- •Текстовые файлы
- •Нетипизированные файлы
- •Переменная FileMode
- •Устройства в Borland Pascal
- •Устройства dos
- •Устройство cоn
- •Устройства lрt1, lрt2 и lрt3
- •Устройства cом1 и cом2
- •Устройство nul
- •Устройства, предназначенные для текстовых файлов
- •Ввод и вывод с помощью модуля Crt
- •Использование модуля crt
- •Окна crt
- •Специальные символы
- •Ввод строк
- •Процедуры и функции модуля Crt
- •Константы и переменные модуля Crt
- •Ввод и вывод с помощью модуля WinCrt
- •Использование модуля WinCrt
- •Специальные символы
- •Ввод строк
- •Процедуры и функции
- •Переменные модуля WinCrt
- •Печать из программы Windows
- •Изменение заголовков
- •Изменение шрифтов
- •Остановка задания печати
- •Специальные символы
- •Процедуры и функции модуля WinPrn
- •Функция Open
- •Функция InOut
- •Функция Flush
- •Функция Clоsе
- •Глава 15. Использование сопроцессора 80x87
- •Типы данных процессора 80x87
- •Арифметические операции с повышенной точностью
- •Сравнение вещественных чисел
- •Стек вычислений сопроцессора 80x87
- •Запись вещественных чисел при использовании сопроцессора 80x87
- •Модули, в которых используется сопроцессор 80x87
- •Распознавание сопроцессора 80х87 в программах dos
- •Распознавание сопроцессора 80x87 в программе Windows
- •Использование эмуляции сопроцессора 80x87 на языке ассемблера
- •Глава 16. Модуль Dоs
- •Процедуры и функции модуля Dos
- •Константы, типы и переменные модуля Dos
- •Переменные модуля Dos
- •Процедуры и функции модуля WinDos
- •Константы, типы и переменные модуля WinDos
- •Переменные модуля WinDos
- •Глава 17. Программирование в защищенном режиме dos
- •Что такое защищенный режим?
- •Расширения Borland защищенного режима dos
- •Dpmi-сервер
- •Администратор этапа выполнения
- •Разработка прикладных программ dos защищенного режима
- •Надежное программирование в защищенном режиме
- •Загрузка в сегментные регистры недопустимых значений
- •Функция Ptr и массивы Mem
- •Абсолютные переменные
- •Операции с сегментами
- •Использование сегментных регистров в качестве временных переменных
- •Доступ к памяти вне границ сегмента
- •Запись в сегмент кода
- •Разыменование указателей nil
- •Сегменты кода и данных
- •Управление динамически распределяемой памятью
- •Предопределенные селекторы
- •Переменная SelectorInc
- •Модуль WinApi
- •Управление памятью
- •Подпрограммы управления памятью api
- •Управление модулем
- •Управление ресурсами
- •Управление селектором
- •Другие подпрограммы api
- •Прямой доступ к dpmi-серверу
- •Компиляция прикладной программы защищенного режима
- •Выполнение программы защищенного режима dos
- •Управление объемом используемой rtm памяти
- •Глава 18. Строки с завершающим нулем
- •Что такое строка с завершающим нулем?
- •Функции модуля Strings
- •Использование строк с завершающим нулем
- •Символьные указатели и строковые литералы
- •Символьные указатели и символьные массивы
- •Индексирование символьного указателя
- •Операции с символьными указателями
- •Строки с завершающим нулем и стандартные процедуры
- •Пример использования функций с завершающим нулем
- •Глава 19. Использование графического интерфейса Borland
- •Драйверы
- •Поддержка устройства ibm 8514
- •Система координат
- •Текущий указатель
- •Графические изображения и их виды
- •Области просмотра и двоичные образы
- •Поддержка страниц и цветов
- •Обработка ошибок
- •Начало работы
- •Пользовательские программы управления динамически распределяемой памятью
- •Процедуры модуля Graph
- •Константы, типы и переменные модуля Graph
- •Константы
- •Переменные
- •Глава 20. Использование оверлеев
- •Администратор оверлеев
- •Управление оверлейным буфером
- •Процедуры и функции модуля Overlay
- •Коды результата
- •Разработка программ с оверлеями
- •Генерация оверлейного кода
- •Требование использования дальнего типа вызовов
- •Инициализация администратора оверлеев
- •Разделы инициализации в оверлейных модулях
- •Что не должно использоваться в качестве оверлеев
- •Отладка оверлеев
- •Внешние программы в оверлеях
- •Задание функции чтения оверлея
- •Оверлеи в файлах .Exe
- •Часть III. В среде Borland Pascal Глава 21. Использование памяти
- •Использование памяти программами реального режима dos
- •Администратор динамически распределяемой области памяти dos
- •Методы освобождения областей динамически распределяемой памяти
- •Список свободных блоков
- •Переменная HeapError
- •Использование памяти в программах dos защищенного режима
- •Сегменты кода
- •Атрибуты сегмента
- •Атрибуты moveable или fixed
- •Атрибуты preload или demandload
- •Атрибуты discardable или permament
- •Сегменты данных и стека
- •Изменение атрибутов
- •Администратор динамически распределяемой области памяти dos
- •Переменная HeapError
- •Использование памяти в программах Windows
- •Атрибуты сегментов
- •Атрибуты moveable или fixed
- •Атрибуты preload или demandload
- •Атрибуты discardable или permanent
- •Изменение атрибутов
- •Сегмент локальных динамических данных
- •Администратор динамически распределяемой области памяти
- •Переменная HeapError
- •Форматы внутреннего представления данных
- •Целочисленные типы
- •Символьный тип
- •Булевский тип
- •Перечислимый тип
- •Типы с плавающей точкой
- •Вещественный тип
- •Тип числа с одинарной точностью
- •Тип числа с двойной точностью
- •Тип числа с повышенной точностью
- •Сложный тип
- •Значения типа указатель
- •Значения строкового типа
- •Значения множественного типа
- •Значения типа массив
- •Значения типа запись
- •Объектные типы
- •Значения файлового типа
- •Процедурные типы
- •Прямой доступ к памяти
- •Прямой доступ к портам
- •Глава 22. Вопросы управления
- •Соглашения по вызовам
- •Параметры-переменные
- •Параметры-значения
- •Открытые строковые параметры
- •Результаты функций
- •Ближние и дальние типы вызовов
- •Вложенные процедуры и функции
- •Соглашения о вызовах методов
- •Вызовы виртуальных методов
- •Вызовы динамических методов
- •Конструкторы и деструкторы
- •Стандартный код входа и выхода
- •Соглашения по сохранению регистров
- •Процедуры выхода
- •Обработка прерываний
- •Разработка процедур обработки прерываний
- •Глава 23. Автоматическая оптимизация
- •Свертывание констант
- •Слияние констант
- •Вычисление по короткой схеме
- •Параметры-константы
- •Устранение избыточной загрузки указателей
- •Подстановка констант множественного типа
- •Малые множества
- •Порядок вычисления
- •Проверка на допустимость границ
- •Использование сдвига вместо умножения
- •Автоматическое выравнивание на границу слова
- •Удаление неиспользуемого кода
- •Эффективная компоновка
- •Часть IV. Использование Borland Pascal с языком ассемблера Глава 24. Встроенный ассемблер
- •Оператор asm
- •Использование регистров
- •Синтаксис операторa ассемблера
- •Размер инструкции ret
- •Автоматическое определение размера перехода
- •Директивы ассемблера
- •Операнды
- •Выражения
- •Различия между выражениями Паскаля и ассемблера
- •Элементы выражений
- •Константы
- •Числовые константы
- •Строковые константы
- •Регистры
- •Идентификаторы
- •Классы выражений
- •Типы выражений
- •Операции в выражениях
- •Процедуры и функции ассемблера
- •Глава 25. Компоновка с программами на языке ассемблера
- •Турбо Ассемблер и Borland Pascal
- •Примеры программ на языке ассемблера
- •Методы на языке ассемблера
- •Включаемый машинный код
- •Операторы Inline
- •Директивы inline
Значения строкового типа
Строка занимает столько байт, какова максимальная длина
строки, плюс один байт. Первый байт содержит текущую динамическую
длину строки, а последующие байты содержат символы строки. Бит
длины и символы рассматриваются, как значения без знака. Макси-
мальная длина строки - 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,
если родительская таблица динамических методов отсутствует.
Второе и третье слово таблицы динамических методов использу-
ется в кеш-буфере просмотра динамических методов (см. далее).
Четвертое слово таблицы динамических методов содержит счет-
чик записи таблицы динамических методов. Непосредственно за ним
следует список слов, каждое из которых содержит индекс динамичес-
кого метода, а затем список соответствующих указателей методов.
Длина каждого списка задается счетчиком записи таблицы динамичес-
ких методов.