Обработка исключений.
Исключительная ситуация – один из ключевых элементов Object Pascal. Идея исключений состоит в том, чтобы сделать программу более надежной, позволяя обрабатывать программные и аппаратные ошибки простым и единообразным способом. Программа при этом может сохранить работоспособность или завершить работу корректно, позволяя пользователю сохранить все данные перед выходом. Технология обработки исключений позволяет отделить код обработки ошибок от смыслового кода. Основной код программы будет в меньшей степени перегружен фрагментами, имеющими отношение к техническим деталям и не связанными с решением основной задачи. Плюсом является то что исключения определяют универсальный стандартный механизм сообщений об ошибках, используемый также компонентами Дельфи.
Если в процессе выполнения программы что – либо работает неверно, Дельфи генерирует исключительную ситуацию. В независимости от того, где произошла ошибка (в коде программы, внутри компонента, в ОС) обработка возникшей проблемы осуществляется унифицировано. В момент возникновения исключения управление передается из кода, ставшего причиной исключения, коду из которого было выполнено обращение. Если исключения в программе никак не обрабатываются они передаются из подпрограммы или метода в вызывающую подпрограмму или метод и так вплоть до глобального обработчика Aplication. Таким образом среда Дельфи сама может обработать исключение, а затем попытается продолжить выполнение программы.
При обработке исключений используются следующие ключевые слова:
Try – помечает начало защищенного участка кода
Except – бозначает конец защищенного участка и начало операторов обработки исключения
Синтаксис следующий:
On тип исключения do действия
Finally – специфицирует код, который выполняется в любом случае, даже если произошло исключение.
В рамках фрагмента кода, помеченного этим ключевым словом, обычно выполняются разного рода завершающие операции, например, закрытие файлов и таблиц данных, уничтожение объектов, освобождение памяти и других ресурсов, задействованных в анализируемом участке кода.
Raise – позволяет породить исключительную ситуацию.
Большинство исключений генерируются системой, но можно самостоятельно породить исключение в программе, например, когда на этапе выполнения обнаруживается некорректность. Кроме того, ключевое слово raise можно использовать внутри обработчика исключений, чтобы породить исключение заново. Это может потребоваться для того, чтобы передать исключение следующему обработчику. Однако, механизм обработки исключений не является заменой необходимости тестирования аргументов функции.
Например, теоретически можно написать следующий код:
Function Ex1(A,B:integer):integer;
Begin
Try
Result:= A div B; //возможно деление на 0
……………….
Result:=Result+1;
Except
On EDivByZero do
Result:=0;
End;
End;
В рассмотренном примере возможно вообще не имеет смысла выполнять обработку исключения, вместо этого следует просто выполнить проверку и отобразить на экране сообщение об ошибке – алгоритм, обратившийся в данной функции не должен продолжать работу, т.к. в рез - е выполнения функции было получено бессмысленное значение.
Использование блока finally.
Пример:
Будут выполняться длительные вычисления а на экране будет отображаться курсов в виде песочных часов.
Function Tform1.Btn1Click(sender:object);
Var I,j:integer;
Begin
Screen.Cursos:=czHourGlass;
J:=0;
For i:=1000 downto 0 do
J := j + j div I; {деление на 0}
messageDlg(‘Total: ’,+IntToStr(j), mtInformation, [mbOK], 0);
screen.Cursos:=csDefault;
End;
При попытке деления на 0 программа прервется, но курсор по умолчанию не будет восстановлен. Для того чтобы исправить ситуацию используется блок try..finally.
Function Tform1.Btn2Click(sender:object);
Var I,j:integer;
Begin
Screen.Cursos:=czHourGlass;
Try
J:=0;
For i:=1000 downto 0 do
J := j + j div I; {деление на 0}
messageDlg(‘Total: ’,+IntToStr(j), mtInformation, [mbOK], 0);
Finally
screen.Cursos:=csDefault;
End;
В данном случае программа восстановит вид курсора в независимости от того, произошло исключение или нет.
Рассмотренный пример не осуществляет обработку исключения, а просто осуществляет корректный выход из программы. За блоком try может следовать либо блок except либо блок finally, но не оба блока одновременно. В случае, если необходимо также добавить и обработку исключения, то стандартное решение – применить два вложенных блока try.
Пример 3
Function Tform1.Btn3Click(sender:object);
Var I,j:integer;
Begin
Screen.Cursos:=czHourGlass;
Try try
J:=0;
For i:=1000 downto 0 do
J := j + j div I; {деление на 0}
messageDlg(‘Total: ’,+IntToStr(j), mtInformation, [mbOK], 0);
Finally
screen.Cursos:=csDefault;
except
on E:EDivByZero do // E – временный объект исключения
begin
raise Exception.Create(‘Ошибка в алгоритме’);
end;
end;
end;
End;
Каждый раз, когда в программу добавляется некий завершающий код, его необходимо размещать в разделе finally. Это будет хорошей защитой от утечек памяти и некорректного использования ресурсов. Обработка самого исключения возможно менее важна т.к. Дельфи с этим нормально справляется.
Классы исключений
В дельфи исключения – это объекты, содержащие информацию, идентифицирующую ошибку и место её возникновения. В рассмотренных примерах осуществляется перехват исключения EDivByZero, определенного в библиотеке RTL среды Дельфи. Существует целый ряд такого рода исключений, относящихся к проблемам, возникающим в процессе выполнения программы. Кроме деления на 0 - неверное динамическое приведение типов, проблемы ресурсов – нехватка памяти, ошибки компонентов, неправильное использование индекса.
Пример.
Будет иллюстрировано как мы должны ориентироваться в иерархиях системы или в своих иерархиях.
Операция деления может генерировать два типа исключения – поэтому добавим в блок exception еще один оператор.
Function TMyClass.Repercent(A,B:integer):real;
Begin
Try
Result:= A/B * 100;
Except
On EDivByZero do {знаменатель равен 0}
Result:=0;
On EInvalidOp do
Result:=0;
End;
End;
Исключения - это объекты, все их типы является потомками базового класса Exception. Существует такая иерархия
Exception
EMathError
EDivByZero EInvalidOp
Таким образом, на основе правил совместимости типов в Object Pascal можно создать следующий обработчик:
Function TMyClass.Repercent(A,B:integer):real;
Begin
Try
Result:= A/B * 100;
Except
On EMathError do {все ошибки математич.вычислений}
Result:=0;
End;
End;
Дата добавления: 2016-07-27; просмотров: 1247;