|
Программирование >> Структурное программирование
Объект производного класса может быть перехвачен или обработчиком, в котором специфицирован этот тип производного класса, или обработчиками, в которых специфицированы типы любых базовых классов этого производного класса. Иногда программа может обрабатывать многие близко связанные типы исключений. Вместо того, чтобы обеспечивать каждое исключение отдельным классом и обработчиком catch, программист может создать один класс исключения и один обработчик catch для группы исключений. При возникновении каждого из таких исключений может создаваться один объект исключения с различными закрытыми данными. Обработчик catch может просматривать эти закрытые данные, чтобы различить типы исключений. Возможно, что, хотя имеется обработчик с точным соответствием типа, будет использовано соответствие, требующее стандартных преобразований, потому что этот обработчик встретится ранее того, который обеспечивает точное соответствие. По умолчанию, если для исключения не найден никакой обработчик, программа завершается. Обработчик исключения не может непосредственно обращаться к переменным в области действия блока try. Информация, необходимая обработчику, обычно передается в сгенерированный объект. Обработчики исключений могут рассмотреть ошибку и решить вызвать функцию terminate. Они могут просто повторно сгенерировать исключение. Они могут преобразовать один тип исключения в другой, генерируя это другое исключение. Они могут выполнить любые необходимые восстановления и продолжить выполнение с первого оператора после последнего обработчика исключения. Они могут рассмотреть ситуацию, вызвавшую ошибку, удалить причину ошибки и повторить вызов первоначальной функции, которая вызвала исключение (это не должно создавать бесконечную рекурсию). Они могут просто возвращать некоторое значение состояния в среду выполнения и т.д. Обработчик, который перехватывает объект производного класса, должен размещаться перед обработчиком, который перехватывает объект базового класса. Если обработчик базового класса был первым, он перехватит как объекты базового класса, так и объекты всех производных классов. Когда исключение перехвачено, возможно, что ресурсы, которые были выделены, еще не освобождены в блоке try. Обработчик catch должен освободить эти ресурсы. Возможно, что обработчик, который перехватил исключение, решит, что он не может сам обработать это исключение. В этом случае обработчик может просто повторно сгенерировать это исключение. Повторное исключение генерируется оператором throw без аргументов. Если никакое исключение не было сгенерировано, то оператор повторной генерации вызывает обращение к функции завершения terminate. Даже если обработчик может обработать исключение и независимо от того, делает ли он какую-либо обработку этого исключения, он может повторно возбудить исключение для последующей обработки его вне этого обработчика. Повторно сгенерированное исключение обнаруживается следующим внешним блоком try и перехватывается обработчиком из списка, следующего за этим внешним блоком try. Функция без спецификации исключений может генерировать любое исключение. Функция обработки непредусмотренных исключений unexpected вызывает функцию, указанную с помощью функции set unexpected. Если нет функции, определенной таким способом, то по умолчанию вызывается функция завершения программы terminate. Функция terminate может быть вызвана различными путями: явно; если сгенерированное исключение не может быть перехвачено; если во время обработки исключения разрушен стек; как заданное по умолчанию действие при вызове unexpected; во время разматывания стека, вызванного исключением, и попытки со стороны деструктора сгенерировать исключение, что вызывает обращение к terminate. Прототипы функций set terminate и set unexpected находятся в заголовочных файлах <terminate.h> и <unexpected.h> соответственно. Функции set terminate и set unexpected возвращают указатели на предыдущие версии функций terminate и unexpected соответственно. Это дает возможность программисту сохранить указатели на эти функции, так что впоследствии они могут быть восстановлены. Функции set terminate и set unexpected получают в качестве аргументов указатели на функции. Каждый аргумент должен указать на функцию, возвращающую тип void и без аргументов. Если последним действием определенной пользователем функции завершения не является завершение работы программы, то автоматически будет вызываться функция abort для прекращения работы программы после выполнения других операторов определенной пользователем функции завершения. Исключение, сгенерированное вне блока try, вызывает завершение программы. Если после блока try обработчик не может быть найден, продолжается разматывание стека, пока соответствующий обработчик не будет найден. Если обработчик так и не найдется, вызывается функция завершения terminate, которая по умолчанию прерывает программу с помощью функции abort. Спецификации исключений перечисляют исключения, которые могут быть сгенерированы в функции. Функция может генерировать обозначенные исключения или типы, производные от них. Если генерируется исключение, не предусмотренное в спецификации, вызывается функция unexpected. Если функция генерирует исключение некоторого класса, то эта функция может также генерировать исключения всех классов, которые являются производными от этого класса. Чтобы перехватить исключение, обработчик должен иметь доступ к конструктору копии сгенерированного объекта. Исключения, генерируемые в конструкторах, обусловливают вызов деструкторов всех объектов-элементов того объекта, который создавался перед генерацией исключения. Если к моменту генерации исключения был частично создан массив объектов, то будут выполняться деструкторы только созданных элементов массива. Исключения, генерируемые деструкторами, можно перехватить, включив функцию вызова деструктора в блок try и предусмотрев обработчик catch соответствующего типа. Преимущества использования наследования для исключений заключается в том, что это дает возможность обработчику исключений перехватывать родственные ошибки, используя очень компактную запись. Конечно, можно было бы перехватывать каждый тип объекта исключения порожденного класса индивидуально, но более удобно перехватить объект исключения базового класса. Терминология abort О catch catch (...) exit О new handler set new handler () set terminate () set unexpected () terminate () throw без аргументов unexpected () аргумент catch асинхронная ошибка блок catch блок try включающий в себя блок try вложенные обработчики исключений возбуждение исключения выражение throw генерация исключения генерация непредусмотренного исключения генерация объекта живучесть программы исключение исключения, не связанные с ошибками макрос assert многоточие (...) как тип перехвата неперехваченное исключение нехватка свободной памяти обработка исключения обработка исключения обработчик для базового класса обработчик для производного класса обработчик исключения обработчик исключения по умолчанию обратный вызов объект исключения объявление исключения оператор try ответственные приложения отказоустойчивость перехват всех исключений перехват группы исключений перехват исключения повторная генерация исключения предложение catch пустая спецификация throw пустая спецификация исключений разматывание стека сгенерированное исключение сгенерированный аргумент синхронная ошибка спецификация исключений список throw список исключений список обработчиков тип сгенерированного объекта точка генерации исключения условное исключение функция без спецификации исключений
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |