- •Введение
- •Как использовать руководства по Borland Pascal
- •Глава 1. Установка и запуск Borland Pascal
- •Использование программы Install
- •Программа Install и Windows
- •Запуск Borland Pascal
- •Защищенный режим и память
- •Запуск Borland Pascal for Windows
- •Запуск bp.Exe в расширенном режиме Windows 386
- •Запуск bp.Exe в стандартном режиме Windows
- •Запуск bp.Exe в окне Windows dos
- •Жидкокристаллические и плазменные экраны
- •Файл readme
- •Файлы filelist.Doc и helpme!.Doc
- •Примеры программ
- •Глава 2. Что нового в Borland Pascal
- •Три интегрированных интерактивных среды разработки программ
- •Новые средства ide
- •Компилятор командной строки, работающий в защищенном режиме
- •Среда разработки программ защищенного режима dos
- •Динамически компонуемые библиотеки dos
- •Добавления к языку Паскаль
- •Улучшения в библиотеке исполняющей системы
- •Новые подпрограммы модуля System
- •Новые модули
- •Новые директивы компилятора
- •Усовершенствования компилятора
- •Улучшения в Turbo Vision
- •Улучшения ObjectWindows
- •Новые средства и утилиты
- •Глава 3. Основы интегрированной среды для dos
- •Запуск ide
- •Компоненты интегрированной среды
- •Окна ide
- •Управление окном
- •Строка состояния
- •Диалоговые окна
- •Глава 4. Программирование в интегрированной интерактивной среде для dos
- •Запуск ide и выход из нее
- •Параметры запуска
- •Установка параметров запуска в интегрированной среде
- •Выход из ide
- •Использование справочной системы Help
- •Перемещение в справочной системе
- •Запрос помощи
- •Копирование примеров исходного кода
- •Загрузка других справочных файлов
- •Выход из справочника Help
- •Запись и редактирование исходного кода
- •Настройка конфигурации редактора
- •Изменение решения: команда Undo
- •Групповая отмена
- •Отмена отмены
- •Работа с блоками текста
- •Выделение блока
- •Вырезание, копирование и вставка блоков
- •Изменение поведения выделенных блоков
- •Поиск и замена
- •Соответствие пар ограничителей
- •Переход к строке с заданным номером
- •Использование локального меню окна редактирования
- •Выделение синтаксиса
- •Выбор файлов для выделения
- •Запрещение выделения синтаксиса
- •Глава 4. Программирование в интегрированной интерактивной среде для dos (часть2) Печать исходного кода
- •Работа с файлами
- •Открытие файлов
- •Открытие файла в позиции курсора
- •Компиляция и выполнение
- •Выбор целевой платформы
- •Компиляция
- •Формирование (Make)
- •Построение (Build)
- •Выполнение
- •Передача программе параметров
- •Параметры компилятора и компоновщика
- •Оптимизация кода
- •Условная компиляция
- •Директивы define и undef
- •Предопределенные идентификаторы
- •Идентификаторы iFxxx, else и endif
- •Директивы ifdef и ifndef
- •Директива ifopt
- •Просмотр исходного кода
- •Просмотр объектов
- •Просмотр модулей
- •Просмотр глобальных идентификаторов
- •Просмотр идентификаторов в исходном коде
- •Просмотр функций ObjectBrowser
- •Выполнение в ide других программ
- •Настройка меню Tools
- •Работа с окном Messages
- •Настройка конфигурации ide
- •Сохранение рабочей операционной среды
- •Использование файла конфигурации
- •Использование файла оперативной области
- •Управление проектом
- •Глава 5. Программирование в интегрированной интерактивной среде для Windows
- •Запуск ide для Windows
- •Использование оперативной полосы
- •Настройка конфигурации оперативной полосы
- •Использование справочной системы Help
- •Перемещение по справочной системе
- •Запрос помощи
- •Копирование примеров кода
- •Выход из справочной системы
- •Запись и редактирование исходного кода
- •Настройка конфигурации редактора
- •Набор команд
- •Использование редактора
- •Выделение синтаксиса
- •Цветовое выделение текста
- •Использование системных цветов Windows
- •Изменение атрибутов текста
- •Печать исходного кода
- •Работа с файлами
- •Открытие файлов
- •Где находятся файлы?
- •Работа с файлами в другом каталоге
- •Компиляция и выполнение
- •Просмотр исходного кода
- •Просмотр объектов
- •Буквенные символы в ObjectBrowser
- •Фильтры
- •Просмотр глобальных идентификаторов
- •Просмотр идентификаторов в исходном коде
- •Выполнение в ide других программ
- •Настройка конфигурации ide
- •Глава 6. Отладка в интегрированной среде
- •Что такое отладка?
- •Какие существуют виды ошибок?
- •Методы отладки
- •Генерация отладочной информации
- •Управление выполнением
- •Что такое шаг?
- •Выполнение программы по шагам
- •Трассировка программы
- •Трассировка или выполнение по шагам?
- •Выполнение больших фрагментов
- •Поиск нужного места
- •Повторное выполнение
- •Отслеживание вывода программы
- •Переключение экранов
- •Окно Output
- •Использование двух мониторов
- •Просмотр значений
- •Что такое выражение?
- •Просмотр выражений
- •Спецификаторы формата в выражениях отладчика
- •Вычисление и модификация
- •Использование точек останова
- •Задание точек останова
- •Отмена точке останова
- •Модификация точек останова
- •Создание условный точек останова
- •Прерывание программы без точек останова
- •Глава 7. Модули Borland Pascal
- •Что такое модуль?
- •Структура модуля
- •Интерфейсная секция
- •Секция реализации
- •Секция инициализации
- •Как используются модули?
- •Ссылки на описания модуля
- •Оператор uses секции реализации
- •Стандартные модули
- •Создание ваших собственных модулей
- •Компиляция модуля
- •Доступность модуля для программы
- •Модули и большие программы
- •Утилита tpumover
- •Глава 7. Модули Borland Pascal
- •Что такое модуль?
- •Структура модуля
- •Интерфейсная секция
- •Секция реализации
- •Секция инициализации
- •Как используются модули?
- •Ссылки на описания модуля
- •Оператор uses секции реализации
- •Стандартные модули
- •Создание ваших собственных модулей
- •Компиляция модуля
- •Доступность модуля для программы
- •Модули и большие программы
- •Утилита tpumover
- •Глава 9. Объектно-ориентированное программирование
- •Объекты
- •Наследование
- •Объекты: наследующие записи
- •Экземпляры объектных типов
- •Поля объектов
- •Хорошая и плохая техника программирования
- •Совмещенные код и данные
- •Определение методов
- •Область действия метода и параметр Self
- •Поля данных объекта и формальные параметры метода
- •Объекты, экспортируемые модулями
- •Секция private
- •Программирование в "действительном залоге"
- •Глава 9. Объектно-ориентированное программирование(часть2) Инкапсуляция
- •Методы: никакого ухудшения
- •Расширяющиеся объекты
- •Наследование статических методов
- •Виртуальные методы и полиморфизм
- •Раннее связывание против позднего связывания
- •Совместимость типов объектов
- •Полиморфические объекты
- •Виртуальные методы
- •Проверка диапазонов при вызове виртуальных методов
- •Расширяемость объекта
- •Статические методы или виртуальные методы?
- •Динамические объекты
- •Размещение и инициализация с помощью процедуры New
- •Удаление динамических объектов
- •Деструкторы
- •Пример размещения динамического объекта
- •Что же дальше?
- •Заключение
- •Глава 10. Взгляд на Windows
- •Что такое приложение Windows?
- •Преимущества Windows
- •Требования
- •Программные средства
- •Архитектура с управлением по событиям
- •Графика, независимая от устройств
- •Многозадачность
- •Управление памятью
- •Ресурсы
- •Динамическая компоновка
- •Буфер вырезанного изображения
- •Динамический обмен данными
- •Множественный документальный интерфейс
- •Типы данных Windows
- •Объектно-ориентированная работа с окнами
- •Лучший интерфейс с Windows
- •Интерфейсные объекты
- •Абстрагирование функций Windows
- •Автоматизация ответа на сообщения
- •Структура программы Windows
- •Структура Windows
- •Взаимодействие с Windows и dos
- •Элементарная программа
- •Действия программы при запуске
- •Назначение основного окна
- •Цикл разработки прикладной программы
- •Изучение ObjectWindows
Пример размещения динамического объекта
Последний пример программы даст вам возможность приобрести
некоторые навыки в использовании размещенных в динамической памя-
ти объектов, включая использование для удаления объекта деструк-
тора. Программа показывает, как в динамической памяти может быть
создан связанный список рабочих объектов и как он за ненадоб-
ностью может быть очищен при помощи деструктора.
Построение связанного списка объектов требует, чтобы каждый
объект содержал указатель на следующий объект списка. Тип
TEmployee не содержит таких указателей. Простым выходом из этой
ситуации было бы добавление указателя в TEmployee , благодаря че-
му можно быть уверенным, что все потомки TEmployee наследуют та-
кой указатель. Однако, добавление чего-либо в TEmployee требует
от вас наличия исходного кода, а как говорилось ранее, одним из
преимуществ объектно-ориентированного программирования является
возможность расширения объектов без необходимости их перекомпиля-
ции.
Решение, которое не требует никаких изменений TEmployee,
создает новый тип объекта, не являющийся потомком TEmployee. Тип
StaffList представляет собой очень простой объект, целью которого
является создание заголовков для объектов типа TEmployee. Так как
TEmployee не содержит никаких указателей на следующий объект в
списке, то простой тип записи TNode осуществляет этот сервис.
TNode даже проще, чем StaffList в том, что TNode не является объ-
ектом, не содержит ни одного метода и не имеет никаких данных, за
исключением указателя на тип TEmployee и указателя на следующий
узел списка.
TStaffList содержит метод, который позволяет ему добавлять
нового рабочего в связанный список записей TNode путем внесение
нового экземпляра TNode непосредственно после самого себя в ка-
честве указуемого с помощью указателя поля TNodes. Метод Add при-
нимает указатель на объект типа TEmployee, но не сам объект.
Из-за расширенной совместимости типов Турбо Паскаля указатели на
любого потомка типа TEmployee также должны передаваться в
TList.Add в параметре Item.
Программа WorkList описывает статическую переменную Staff
типа TStaffList и строит связанный список из пяти узлов. Каждый
узел указывает на отдельный рабочий объект, который является либо
TEmployee, либо одним из его потомков. Перед созданием каждого
динамического объекта и после того, как объект создан, возвращает
число байт свободной динамической памяти. Наконец, полная струк-
тура, включающая пять записей TNode и пять объектов типа
TEmployee, очищается и удаляется из динамической памяти с помощью
одного вызова деструктора статического объекта Staff типа
TStaffList.
|
List | Node Node Node
+-------+ +----+----+ +----+----+ +----+----+
| | | | | | | | | | | |
| O--+----> | O | O-+---> | O | O-+----> | O | O-+---+
| | | | | | | | | | | | | | | |
+-------+ +--+-+----+ +--+-+----+ +--+-+----+ |
| | | | --+--
v v v ---
| +-------------+ +-------------+ +-------------+ -
| Name | | Name | | Name |
| +-------------| +-------------| +-------------|
| Title | | Title | | Title |
| +-------------| +-------------| +-------------|
| Rate | | Rate | | Rate |
| +-------------| +-------------| +-------------|
| | | | | |
Сегмент | Динамически распределяемая область
данных памяти (динамический)
(статические|
объекты)
|
Рис. 9.2 Схема структур данных программы ListDemo.
Удаление сложной структуры данных из динамической памяти
Деструктор Staff.Done стоит того, чтобы рассмотреть его вни-
мательно. Уничтожение объекта TStaffList включает удаление трех
различных типов структур: полиморфических объектов рабочих струк-
тур в списке, записей TNode, поддерживающих список, и (если он
размещен в динамической памяти) объект TList, который озаглавли-
вает список. Весь процесс запускается путем единственного вызова
деструктора объекта TStaffList:
Staff.Done;
Код деструктора заслуживает более подробного изучения:
destructor StaffList.Done;
var
N: TNodePtr;
begin
while TNodes <> nil do
begin
N := TNodes;
Disрose(N^.Item, Done);
TNodes := N^.Next;
Disрose (N);
end;
end;
Список очищается начиная с "головы" списка с помощью алго-
ритма "из руки в руку", который до некоторой степени напоминает
дерганье за веревку воздушного змея: два указателя (указатель
TNodes внутри Staff и рабочий указатель N) изменяют свои ссылки в
списке, тогда как первый элемент списка удаляется. Вызов процеду-
ры Disрose освобождает память, занимаемую первым объектом
TEmployee в списке (Item^), затем TNodes продвигается на следую-
щую запись списка с помощью оператора TNodes := N^.Next, сама за-
пись TNode удаляется, и процесс продолжается до полного очищения
списка.
Важным моментом в деструкторе Done является способ, которым
удаляются из списка объекты TEmployee:
Disрose(N.Item, Done);
Здесь N.Item является первым объектом TEmployee в списке, а
вызываемый метод Done является деструктором этого объекта. Запом-
ните, что действительный тип N^.Item^ не обязательно является ти-
пом TEmployee, однако он может быть любым дочерним типом типа
TEmployee. Очищаемый объект является полиморфическим и поэтому
нельзя сделать никаких предположений относительно его действи-
тельного размера или точного его типа на этапе компиляции. В при-
веденном выше вызове Disрose, как только Done выполнит все содер-
жащиеся в нем операторы, "невидимый" код эпилога ищет размер реа-
лизации очищаемого объекта в ТВМ этого объекта. Метод Done пере-
дает размер процедуре Disрose, которая затем освобождает точное
количество динамической памяти, в действительности занимаемой по-
лиморфическим объектом.
Помните, что если должно освобождаться правильное количество
динамической памяти, то полиморфический объект должен очищаться
только посредством вызова передаваемого Disрose деструктора.
В примере программы Staff объявляется как статическая пере-
менная в сегменте данных. Staff мог бы столь же легко разместить-
ся в динамической памяти и "прикрепиться к реальному миру" пос-
редством указателя типа ListPtr. Если заголовок списка также яв-
ляется динамическим объектом, то удаление структуры можно осу-
ществить путем вызова деструктора, выполняющегося внутри Disрose:
var
Staff: TStaffListPtr;
begin
Disрose(Staff, Done);
.
.
.
Здесь процедура Disрose вызывает метод деструктора Done для
очистки структуры в динамической памяти. Затем, когда Done завер-
шается, Disрose освобождает память, на которую указывает Staff,
удаляя, как правило, из динамической памяти также и заголовок
списка.
Программа WORKLIST.PAS (находящаяся на вашем диске) исполь-
зует тот же модуль WORKERS.PAS, что и раньше Она создает объект
List, являющийся оглавлением связанного списка из пяти полиморфи-
ческих объектов, совместимых с TEmployee, а затем удаляет всю ди-
намическую структуру данных с помощью единственного вызова дест-
руктора Staff.Done.