Введение в исключительные ситуации

Исключительные ситуации

Исключительные ситуации — новые "любимчики" ANSI C++, но до тех пор, пока вы не научитесь ими пользоваться, они могут показаться вам скорее дьявольскими, чем любимыми. Немногие программисты на C++ пользуются исключительными ситуациями в коммерческих программах — они слишком новы, и немногие компиляторы их поддерживают. Конечно, в некоторых библиотеках классов, таких как Borland's Object Windows (OWL), исключительные ситуации используются весьма интенсивно, так что важно понимать, как они работают.

Это введение в исключительные ситуации — переработанная глава 2 моей книги Mastering Windows Programming with Borland C++ 4.

Исключительные ситуации пришли со своей собственной терминологией и концепциями. Следующие не­сколько замечаний призваны помочь вам прочесть и понять этот раздел.

• Исключительная ситуация — это не что иное, как условие исключительной ситуации, требующее специальной обработки. Исключительные ситуации лучше всего использовать для обработки ошибок, возникающих при выполнении, однако их применение этим не ограничивается.

• Для возбуждения исключительной ситуации оператор посылает (throw) объект, описывающий суть исключительной ситуации. Объект может быть литеральным значением, строкой, объектом класса или любым другим объектом. {Объект исключительной ситуации не обязательно должен быть объектом класса.)

• Для обработки исключительной ситуации некоторый оператор перехватывает (catch) условие, посланное некоторым другим процессом. Операторы, перехватывающие исключительные ситуации, называются обработчиками исключительных ситуаций.

• Программы подготавливаются к перехвату исключительных ситуаций, испытывая (try) один или несколько процессов, возбуждающих исключительные ситуации. В общем, для использования исключительных ситуаций вы испытываете один или несколько операторов и перехватываете любую исключительную ситуацию, которая возбуждается этими операторами.

Обнаружив состояние ошибки, функция может возбудить исключительную ситуацию, что вызовет такие последствия.

• Функция объявляет, что возникло условие исключительной ситуации. Это может быть как ошибкой, так и любым другим обстоятельством, нуждающимся в специальной обработке.

• Функция запрашивает решения проблемы обработчиком исключительной ситуации. Обработчик, если он существует, вызывается автоматически в ответ на посылку объекта исключительной ситуации.

В программе возбуждается исключительная ситуация с помощью выполнения оператора throw, обычно где-нибудь внутри функции:

throw 1;

Однако вы ведь не будете рассылать повсюду целые числа — они способны сообщить не слишком много информации. Более подходящий объект для посылки — строка:

throw "overflow";

Это гораздо осмысленнее. Где-нибудь в другом месте программы обработчик строковых исключительных ситуаций может поймать и отобразить на дисплее посланный объект. В обработчике задается тип объекта (в этом примере — const char*) в выражении catch:

catch (const char* message) {

cout « "Error! -- " « message « endl;

// ... Другие действия в ответ на исключительную ситуацию

. } "

Оператор catch ловит посланные объекты строковых исключительных ситуаций и отображает их операто­ром вывода в поток. Что произойдет дальше — зависит от вас. Если вы не определите дальнейшие действия, программа продолжит свою работу после catch. Вы можете также аварийно прервать выполнение программы, вызвать другую функцию или продолжить цикл для повторного выполнения действий, вызвавших проблему. Исключительная ситуация — механизм для сообщений и принятия мер в случае возникновения условия ис­ключительной ситуации. Исключительные ситуации не навязывают вам необходимых действий. Их обработка полностью зависит от вас.

Особенно важно понять что функции исключительных ситуаций не ограничены обработкой ошибок, что бы ни говорилось в вашем описании Borland G++ и в других источниках. Например, пустой списочный объект может сообщать о том, что он пуст, путем возбуждения исключительной ситуации. Произошла ошибка или что-нибудь еще, зависит только от того, как вы назначите аварийные прерывания выполнения программ. Наверное, вы согласитесь, что неспособность открыть файл — ошибка. Однако является ли отсутствие заданной строки в файле ошибкой или это просто один из возможных, но не исключительных, результатов, о которых может сообщить функция поиска? В зависимости от вашего ответа на этот вопрос, исключительные ситуации могут вам пригодиться или же нет для принятия соответствующих мер в случае неудавшихся поисков или опустевших списков.

Поскольку использование исключительных ситуаций может привести к двусмысленностям в программах, вероятно, их лучше всего использовать для принятия мер в случае возникновения настоящих ошибок, которые могут заставить программу прервать процесс и которые, если их не принять к сведению, могут привести к аварийному завершению программы или же к неверным результатам. Ограничение применения исключительных ситуаций только случаями возникновения действительно исключительных состояний помогает отделить нормальные операторы от тех, что выполняют обработку критических ошибок. Это одна из самых труднодостижимых целей в написании любых программ, за исключением очень небольших по размеру.