Теперь пора познакомиться с исключительными ситуациями. Для чего они нужны? Допустим, что у вас есть участок кода, где может произойти ошибка. Как сделать так, чтобы программа не зависла при ее возникновении? Очень просто — нужно сделать все, чтобы ошибка не возникла. Да, это действительно так. Первым делом, когда пишете код, вы должны делать все, чтобы исключительные ситуации не возникали, а для этого нужно проверять все переменные, параметры и результаты работы функций. Исключительные ситуации — это не панацея, решающая все проблемы, это всего лишь вспомогательный инструмент.
Итак, если вы видите участок кода, который может завершиться ошибкой, надо заключить этот код в блок проверки исключений, и тогда ваша программа выдержит даже "цунами".
Итак, простейший блок исключений выглядит следующим образом:
Рассмотрим простейший пример.
Между try и except у нас стоит маленькое действие — деление на ноль. Компьютер не умеет делать такие вещи (на ноль делить нельзя), поэтому произойдет ошибка и выполнится код между except и end. Если бы не было блока try, то после возникновения ошибки процедура закончила бы выполнение, и все остальные операторы не были бы выполнены, как, например, в нашем случае— х:=о. При использовании try.. .except не будут выполнены только операторы между строкой, которая стала причиной ошибки, и except. После оператора except.. .end все будет выполняться, как будто ничего не произошло.
Если бы мы поменяли 0 на любое другое число, то ошибки бы не было, и код между except и end никогда не выполнился бы.
Такой блок можно использовать не только для вывода сообщения о произошедшей ошибке, он и исправит ситуацию. Например, в нашем случае, если между try и except произошла ошибка, то между except и end можно присвоить переменной х значение по умолчанию на случай ошибки и продолжить выполнять процедуру с этим значением.
Давайте рассмотрим следующий пример:
В этом примере мы создаем объект ь типа TBitmap (картинка). Потом начинаем блок try. В этом блоке мы пытаемся начать рисование. Если во время рисования произошла ошибка, то можно сообщить об этом пользователю и освободить память b. free. После этого происходит выход из процедуры с помощью оператора exit. Если ошибок не было, то просто освобождается память b.free. Если в блоке except не произвести выход, то произойдет ошибка, когда память картинки будет освобождаться второй раз.
Теперь давайте разберемся с еще одним типом исключительных ситуаций — try...finally
Если ошибок не было, то просто освобождается память b.free. Если в блоке except не произвести выход, то произойдет ошибка, когда память картинки будет освобождаться второй раз.
Между try и finally вы пишете свой сомнительный код, в котором может произойти ошибка. А между finally и end пишется код, который должен выполниться вне зависимости от результата кода между try и finally.В этом случае мы не можем информировать пользователя об ошибке, потому что в разделе finally мы не знаем, произошла ошибка или нет. Зато работа с памятью упрощается:
Подобный пример уже рассматривался. В данном случае мы создаем объект ь и пытаемся рисовать. В разделе finally, который выполняется всегда, вне зависимости от того, была ошибка или нет, мы удаляем созданный объект b. Теперь мы уверены, что b всегда будет удален корректно, и выделенная память будет освобождена. Таким образом, код между finally и end будет выполняться всегда вне зависимости от произошедших ошибок.
Будьте внимательны. Ошибки могут появиться даже в самых неожиданных местах. Пользователь очень часто может нажать не туда, куда надо, и сбивать программу с пути правильного выполнения. Конечно же, можно говорить, что пользователь безрукий, но этот безрукий вам платит за то, чтобы программа работала. Поэтому от его действий нужно предохраняться. Исключительные ситуации — один из лучших способов.
Исключительные ситуации я рекомендовал бы использовать в следующих случаях:
- при выделении каких-либо ресурсов, например, памяти, чтобы гарантировать, что выделенные ресурсы всегда будут освобождены корректно;
- при обращении к каким-то ресурсам, например, к диску, памяти и т. д.