Обработка исключений.
7.1. Исключения.
Синтаксически исключение (exception) – это объект произвольного типа, а обработка исключений – это механизм для передачи управления и исключения в специальный блок, который называется обработчиком исключения. Механизм обработки исключения состоит из четырех компонент: исключения, инструкции throw, try-блока и catch-блока, которые организованы следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
try { … // произвольные операторы throw исключение; … // произвольные операторы } catch(тип_исключения) { … // обработка исключения } |
где инструкция throw выбрасывает исключение; блок try содержит код, который может выбросить исключение; блок catch описывает обработчик исключения и должен следовать непосредственно за блоком try. Допускается использование нескольких последовательных блоков catch. Если внутри блока try произошел выброс исключения, то управление передается первому обработчику исключения, тип которого соответствует типу выброшенного исключения. После обработки исключения управление передается на первую инструкцию, которая следует за последним обработчиком исключения. Например,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream.h> int main( ) { int n, m; try { cout << "Input two integers: "; cin >> n >> m; if (!m) throw "Zero divide"; cout << "n/m = " << (n/m) << endl; } catch(char* str) { cout << str << endl; } cout << "OK" << endl; return 1; } |
Часто вся информация об исключении определяется только его типом. В этом случае для типа исключения используют пустые структуры. Например, в нашем случае можно было бы определить исключение типа
struct Zero_divide {};
Тогда наша программа выглядела бы следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <iostream.h> struct Zero_divide {}; int main( ) { int n, m; try { cout << "Input two integers: "; cin >> n >> m; if (!m) throw Zero_divide(); cout << "n/m = " << (n/m) << endl; } catch(Zero_divide) { cout << "Zero divide" << endl; } cout << "OK" << endl; return 1; } |
Обратим внимание на то, что оператор throw должен выбросить объект типа Zero_divide, а не сам тип. Поэтому в этом операторе используется конструктор по умолчанию для объекта типа Zero_divide.