Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

2.4. Исключения 95

Обработка вышеупомянутого блока попытки сделана следующим образом. Вычисления попытки

блок выполнен. То, когда попытка, как обнаруживают, делится на ноль, ZeroDivide брошен, и выполнение немедленно подскакивает к связанному заявлению выгоды, где корректирующее восстановление и моется, должно быть выполнено.

Давайте изучим весь процесс в несколько больших деталях. Заявление броска, как правило, пишется следующим образом:

имя исключения броска (arg1, arg2...), куда аргументы переданы конструктору исключения.

Исключения могут также быть брошены C ++ сама система во время выполнения. Например, если попытка выделить место в свободном магазине, используя нового оператора терпит неудачу из-за недостатка места, то плохое alloc исключение брошено системой.

Когда исключение брошено, оно должно быть поймано, или программа прервется. В любой особой функции через исключение в той функции можно пройти к функции запроса, или это может быть поймано в той функции. Когда исключение поймано, оно может быть проанализировано и имело дело с. Общий синтаксис для блока выгоды попытки в C ++ следующие:

t ry

попробуйте заявления

выгода (идентификатор типа 1 исключения 1)

заявления выгоды 1... выгода (идентификатор типа n исключения n)

заявления выгоды n

Выполнение начинается в «заявлениях попытки». Если это выполнение не производит excep-tions, то flow контроля продолжает первое заявление после последней линии всего блока выгоды попытки. Если с другой стороны исключение произведено, execu-tion в блоке попытки заканчивается в том пункте и скачках выполнения в первый блок выгоды, соответствующий брошенному исключению. Таким образом исключение, брошенное для производного класса, будет поймано его базовым классом. Например, если бы мы бросили NegativeRoot в пример выше, это было бы поймано блоком выгоды для MathException. Обратите внимание на то, что, потому что система выполняет первый блок выгоды соответствия, исключения должны быть перечислены в порядке самого определенного для наименее определенного. Специальная форма «выгода (...)» ловит все исключения.

«Идентификатор» для заявления выгоды определяет сам объект исключения. Как мы сказали прежде, этот объект обычно содержит дополнительную информацию об исключении, и к этой информации можно получить доступ из блока выгоды. Как распространено мимоходом аргументы класса, исключение, как правило, передается как ссылка или постоянная ссылка. Как только выполнение блока выгоды заканчивает, контроль flow продолжает первое заявление после последнего блока выгоды.

Меры восстановления, принятые в блоке выгоды, зависят очень от особого применения. Это может быть столь же просто как печать сообщения об ошибке и завершение

96

Глава 2. Ориентированная на объект программа Дизайна. Это может потребовать сложных операций по зачистке местности, таких как освобождение dynam-ically ассигнованное хранение и восстановление внутреннего состояния программы. Есть также некоторые интересные случаи, в которых лучший способ обращаться с исключением состоит в том, чтобы проигнорировать его (который может быть определен при наличии пустого блока выгоды). Игнорирование исключения обычно делается, например, когда программист не заботится, было ли исключение или нет. Другой законный способ обращаться с исключениями состоит в том, чтобы бросить другое исключение, возможно то, которое определяет исключительное условие более пред - cisely.

2.4.3 Спецификация исключения

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

У этого соглашения есть и функциональная и учтивая цель. Для одного это сообщает пользователям, что ожидать. Это также позволяет компилятору знать который исключения подготовиться к. Ниже приведен пример такого определения функции.

недействительный калькулятор () бросок (ZeroDivide, NegativeRoot)

//тело функции...

Это определение указывает что калькулятор функции (и любые другие функции это

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

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

Следующее иллюстрирует исключение, через которое «проходят».

пустота getReadyForClass () бросок (ShoppingListTooSmallException,

OutOfMoneyException)

goShopping ();//я не должен попробовать или поймать исключения

//который мог бы бросить goShopping (), потому что//getReadyForClass () просто проведет их.

makeCookiesForTA ();

Функция может объявить, что бросает столько исключений, сколько ей нравится. Такой

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