Язык программирования C++ для профессионалов



           

Группирование особых ситуаций - часть 2


try { // ... } catch (Overflow) { /* ... */ } catch (Underflow) { /* ... */ } catch (Zerodivide) { /* ... */ } // ...

Это не только утомительно, но и опасно, поскольку можно забыть какую-нибудь особую ситуацию. Кроме того, необходимость перечислить в проверяемом блоке все особые ситуации практически гарантирует, что, когда семейство особых ситуаций библиотеки расширится, в программе пользователя возникнет ошибка. Это значит, что при введении новой особой ситуации в библиотеки математических функций придется перетранслировать все части программы, которые содержат обработчики всех особых ситуаций из Matherr. В общем случае такая перетрансляция неприемлема. Часто даже нет возможности найти все требующие перетрансляции части программы. Если такая возможность есть, нельзя требовать, чтобы всегда был доступен исходной текст любой части большой программы, или чтобы у нас были права изменять любую часть большой программы, исходный текст которой мы имеем. На самом деле, пользователь не должен думать о внутреннем устройстве библиотек. Все эти проблемы перетрансляции и сопровождения могут привести к тому, что после создания первой версии библиотеки будет нельзя вводить в ней новые особые ситуации. Но такое решение не подходит практически для всех библиотек.

Все эти доводы говорят за то, что особые ситуации нужно определять как иерархию классов (см. также §9.6.1). Это, в свою очередь, означает, что особые ситуации могут быть членами нескольких групп:

class network_file_err // ошибки файловой системы в сети : public network_err, // ошибки сети public file_system_err { // ошибки файловой системы // ... };

Особую ситуацию network_file_err можно перехватить в функциях, обрабатывающих особые ситуации сети:

void f() { try { // какие-то операторы } catch (network_err) { // ... } }

Ее также можно перехватить в функциях, обрабатывающих особые ситуации файловой системы:

void g() { try { // какие-то другие операторы } catch (file_system_err) { // ... } }

Это важный момент, поскольку такой системный сервис как работа в сети должен быть прозрачен, а это означает, что создатель функции g() может даже и не знать, что эта функция будет выполняться в сетевом режиме.

Отметим, что в настоящее время нет стандартного множества особых ситуаций для стандартной математической библиотеки и библиотеки ввода-вывода. Задача комитетов ANSI и ISO по стандартизации С++ решить нужно ли такое множество и какие в нем следует использовать имена и классы.

Поскольку можно сразу перехватить все особые ситуации (см. §9.3.2), нет настоятельной необходимости создавать для этой цели общий, базовый для всех особых ситуаций, класс. Однако, если все особые ситуации являются производными от пустого класса Exception (особая ситуация), то в интерфейсах их использование становится более регулярным (см. §9.6). Если вы используете общий базовый класс Exception, убедитесь, что в нем ничего нет кроме виртуального деструктора. В противном случае такой класс может вступить в противоречие с предполагаемым стандартом.




Содержание  Назад  Вперед