Страница 72 из 74 160. По возможности возбуждайте объекты типа error.
Листинг 15 показывает простую систему определений класса для возбуждения исключений. Я могу перехватить ошибки чтения или записи подобным образом: try { file f("name", "rw"); buffer b; b = f.read() f.write( b ); } catch( file::open_error ?r ) { // Файл не существует или не может быть открыт.} catch( file::io_error ?r ) { // Какая-то из неисправимых ошибок ввода/вывода.}Если меня волнует лишь то, что произошла ошибка определенного вида, и не волнует, какого конкретно, то я могу сделать так: file f; try { buffer b; b = f.read() f.write( b ); } catch( file::error ?r ) { // ...}Листинг 15. Классы исключений - class file
- {
- public:
- class error {};
- class open_error : public error {};
- class io_error : public error {};
- // ...
- }
Этот код работает, потому что объект file::read_error является объектом типа file::error (так как относится к производному классу). Вы всегда можете перехватить объект производного класса, используя ссылку или указатель базового класса. Я мог бы также предложить другой класс, использующий тот же самый механизм: class long_double { public: class error {}; class didvide_by_zero : public error {}; // ... };Так как классы error являются вложенными определениями, то именами на самом деле являются file::error и long_double::error, поэтому здесь нет конфликта имен. Для упрощения сопровождения я всегда использую error в качестве своего базового класса для исключений. (Я не мог использовать производный класс, даже если здесь был бы возможен всего один вид ошибки). Таким образом, я знаю, что имея возбуждающий исключение класс some_class, можно перехватить это исключение при помощи: catch(some_class::error ?r)Эту ошибку искать не придется. Если применяется наследование, то я использую базовый класс error таким образом: class employee { public: class error {}; class database_access_error : public error {}; }; class peon : public employee { class error : public employee::error {}; class aagh : public error {}; };Этим способом исключение aagh может быть перехвачено как peon::aagh, peon::error или employee::error. Нет смысла создавать класс глобального уровня error, от которого наследуются все локальные классы error, потому что для обработки этой ситуации вы можете использовать обработчик catch(...). |