Исключительная ситуация как класс
Таблица 3.1. Исключительные ситуации при работе с памятью (порождены от EHeapException).
Тип | Условие возникновения |
---|---|
EOutOfMemory | Недостаточно места в куче (памяти) |
EOutOfResources | Нехватка системных ресурсов |
EInvalidPointer | Недопустимый указатель (обычно nil) |
Таблица 3.2. Исключительные ситуации целочисленной математики (порождены от EIntError).
Тип | Условие возникновения |
---|---|
EDivByZero | Попытка деления на ноль (целое число) |
ERangeError | Число или выражение выходит за допустимый диапазон |
EIntOverflow | Целочисленное переполнение |
Таблица 3.3. Исключительные ситуации математики с плавающей точкой (порождены от EMathError).
Тип | Условие возникновения |
---|---|
EInvalidOp | Неверная операция |
EZeroDivide | Попытка деления на ноль |
EOverflow | Переполнение с плавающей точкой |
EUnderflow | Исчезновение порядка |
EInvalidArgument | Неверный аргумент математических функций |
Для этого используется оператор raise, за которым в качестве параметра должен идти экземпляр объекта типа Exception. Обычно сразу за оператором следует конструктор класса ИС:
raise EMathError.Create(' ');
Но можно и разделить создание и возбуждение исключительной ситуации:
var E: EMathError; begin E: = EMathError.Create С'); raise E; end;
Оператор raise передает созданную исключительную ситуацию ближайшему блоку try..except (см. ниже).
if С = 0 then raise EDivByZero.Create('Деление на ноль') else А: = В/С;
Самостоятельная инициализация ИС может пригодиться при программировании реакции приложения на ввод данных, для контроля значений переменных и т. д. В таких случаях желательно создавать собственные классы ИС, специально приспособленные для ваших нужд. Также полезно использовать специально спроектированные исключительные ситуации при создании собственных объектов и компонентов. Так, многие важнейшие классы VCL – списки, потоки, графические объекты – сигнализируют о своих (или ваших?) проблемах созданием соответствующей ИС – EListError, EInvalidGraphic, EPrinter и т. д.
Самый важный отличительный признак объекта Exception – это все же класс, к которому он принадлежит. Именно факт принадлежности возникшей ИС к тому или иному классу говорит о том, что случилось. Если же нужно детализировать проблему, можно присвоить значение свойству Message. Если и этого мало, можно добавить в объект новые поля. Так, в ИС EinOutError (ошибка ввода/вывода) есть поле ErrorCode, значение которого соответствует произошедшей ошибке – запрету записи, отсутствию или повреждению файла и т. д.
try .FileOpenС с:\myfile.txt', fmOpenWrite); except on E: EinOutError do case E.ErrorCode of ERROR_FILE_NOT_FOUND {=2}: ShowMessage('Файл не найден!'); ERROR_ACCESS_DENIED {=5}: ShowMessage('Доступ запрещен!'); ERROR_DISK_FULL {=112}: ShowMessage ('Диск переполнен!'); end; end;
Впрочем, ИС EInOutError возникают только тогда, когда установлена опция компилятора {$IOCHECKS ON} (или иначе {$I+}). В противном случае проверку переменной IOResult (известной еще по Turbo Pascal) нужно делать самому.
Еще более "продвинутый" пример – ИС EDBEngineError. Она имеет свойства ErrorCount и свойство-массив Errors: одна операция с базой данных может породить сразу несколько ошибок.