Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 700269.doc
Скачиваний:
15
Добавлен:
01.05.2022
Размер:
1.78 Mб
Скачать

3.4.9. Оператор with...Do

Оператор with...do используется для сокращения кода при обращении к полям записей или к свойствам и методам объекта. Применение этого оператора позволяет избежать повторных ссылок на объект в последующих операторах. Оператор with...do может записываться следующим образом:

with <объект> do <оператор>;

В операторе, следующем за ключевым словом do, можно для полей, свойств и методов объекта, указанного как <объект>, не включать ссылки на этот объект. При этом каждый идентификатор в операторе, который совпадает с именем поля, свойства, метода объекта, трактуется как относящийся к этому объекту, и к нему неявно добавляется ссылка на этот объект.

Возможна другая форма этого оператора, соответствующая множеству вложенных друг в друга конструкций with.

with <объект 1>, ..., <объект n> do <оператор>;

3.5. Обработка исключительных ситуаций

Важным и принципиальным отличием Object Pascal от Pascal является механизм обработки исключительных ситуаций (исключений).

Исключение – это объект специального вида, возникающий, как правило, во время функционирования ПО как реакция на какие-либо ошибки. Это может быть деление на ноль, выход операнда за диапазон и т.д., – словом, ошибки времени выполнения программы. Исключения могут генерироваться автоматически или целенаправленно. Могут также содержать в виде свойств некоторую уточняющую информацию, т.е. характеризовать исключительную ситуацию. Особенностью исключений является то, что это сугубо временные объекты, и после обработки каким-то обработчиком они разрушаются.

Стандартной реакцией ПО на большинство исключений является выдача пользователю краткой информации в окне сообщений и уничтожение экземпляра исключения (обеспечивается методом HandleException). После этого работа программы может быть продолжена.

Механизм обработки исключений предназначен для реализации иной реакции приложения на ошибки времени выполнения. Для этого используются структуры try...except и try...finally.

Первая имеет следующий синтаксис.

try

...{Исполняемый код}

except

on ...<реакция на событие 1>;

on ...<реакция на событие 2>;

...

else

...<обработчик всех не перехваченных ранее событий>;

end;

Операторы, расположенные в разделе except, выполняются только в том случае, если в операторах раздела try (или в процедурах и функциях, вызванных этими операторами) возникла ошибка и, следовательно, было сгенерировано исключение. Раздел except может использоваться двумя способами. При первом способе в нем могут располагаться любые выполняемые операторы, кроме обработчиков исключений on...do. Это могут быть операторы сообщений об ошибке, операторы освобождения ресурсов и т.д. Второй и главный способ использования раздела except – обработка исключений. В этом случае в него могут включаться только обработчики исключений: операторы on...do и необязательный обработчик любых исключений, предваряемый ключевым словом else, как показано в примере.

Оператор on...do перехватывает исключения указанного класса и всех производных от него классов. Поэтому при его использовании важно представлять себе иерархию классов исключений. Структура работает следующим образом. Если при выполнении операторов раздела try генерируется исключение, выполнение этого раздела прерывается и управление передается операторам раздела except. Если среди обработчиков встретился соответствующий сгенерированному исключению, выполняется оператор этого обработчика, исключение разрушается и управление передается оператору, следующему за блоком on...do (т.е. оператору, следующему за последним оператором блока end). Если же обработчик не найден, то управление передается на следующий уровень, т.е. разделу except следующего обрамляющего блока try...except (если таковой есть). То же самое происходит, если в процессе обработки генерируется новое исключение (при обработке ошибки произошла новая ошибка). Если в результате прохода по всем уровням подходящий обработчик так и не будет найден, произойдет обработка системным обработчиком исключений.

Оператор on...do имеет две формы:

on < класс исключения> do <оператор>;

on <имя>: <класс исключения>

do <операторы, в которых можно использовать конструкцию <имя>.<имя свойства>>

Первая форма оператора не позволяет получить доступ к свойствам исключения. Обрабатывается только указанный класс исключений (или исключения, производные от этого класса), обеспечивая индивидуальную реакцию на каждый вид исключений. Таким образом, поскольку семейство исключений построено по иерархическому принципу, можно, обратившись к базовому классу некоторой группы родственных исключений, обработать сразу всю группу.

Вторая форма создает временное имя исключения и позволяет через него с помощью конструкции <имя>.<имя свойства> иметь доступ к свойствам исключительной ситуации.

Обработчик, начинающийся с ключевого слова else, обрабатывает исключения всех классов. Если он используется, то помещается последним в разделе except блока try...except, так как после него любое исключение разрушается и, следовательно, никакой другой обработчик исключений не сработает. Обработчик else позволяет не вводить обработчики on...do всех возможных исключений, которые, следовательно, могут быть введены только для тех исключений, которые требуется обработать особым образом. Остальные могут обрабатываться одним общим обработчиком. При этом с помощью функций ExceptObject, ExceptAddr, ShowException, ClassName и других может быть получен доступ к объекту исключения и выдана информация о типе исключения.

Следует предупредить о некоторой опасности применения обработчика else. Поскольку он обрабатывает все исключения, то, если при этом не выдается никаких сообщений, возможна маскировка ошибок, что может существенно затруднить отладку приложения. Следует также отметить, что else – не единственный способ реализации обработчика любых исключений. Те же функции можно реализовать с помощью обработчика on...do, примененного к базовому классу исключений Exception. Все предопределенные в Delphi классы исключений являются прямыми или косвенными наследниками этого класса. Пользователь может создавать и свои собственные, производные от Exception, классы исключений.

В структуре try...finally программный код, относящийся к секции finally, выполняется при любых условиях, даже если при выполнении операторов раздела finally случилась ошибка, операторы раздела все-таки выполняются до конца. Обычно в этот раздел помещают необходимые операторы "зачистки": освобождения динамически выделенной памяти, закрытия ненужных файлов, удаления временных файлов и т.д. Если не помещать такие операторы в защищенный раздел finally, то из-за прерывания выполнения вследствие возможных ошибок они могут оказаться не выполненными, что приведет к "утечке ресурсов".

Отметим, что блоки try...except никак не связаны с блоками try...finally. На практике эти виды блоков часто используются совместно в виде следующей структуры:

try {начало блока try...finally}

................

try {начало блока try...except}

................

except

................

end; {конец блока try...except}

finally

................

end; {конец блока try...finally}