|
Программирование >> Структурное программирование
Типичная ошибка программирования 13.8 Размещение обработчика исключения с типом аргумента void перед обработчиками исключений с другими типами указателей вызывает синтаксическую ошибку. Обработчик void * будет перехватывать все исключения типа указатель, так что другие обработчики никогда не будут выполняться. Возможно, что хотя имеется обработчик с точным соответствием типа, будет использовано соответствие, требующее стандартных преобразований, потому что этот обработчик встретится ранее того, который обеспечивает точное соответствие. тельность записи обработчиков будет влиять на способ, которым эти исключения будут обрабатываться. Может оказаться, что несколько обработчиков catch содержат тип класса, который соответствует типу конкретного сгенерированного объекта. Это может случиться по нескольким причинам. Во-первых, может существовать обработчик catch (.,.), который перехватит любое исключение. Во-вторых, из-за иерархии наследования может оказаться, что объект производного класса может быть перехвачен как обработчиком данного класса, так и обработчиком любого базового класса, от которого порожден данный класс. Типичная ошибка программирования 13.7 Размещение catch, который перехватывает объект базового класса, перед catch, который перехватывает объект класса, производного от данного базового, является синтаксической ошибкой. Перехватчик catch базового класса перехватит все объекты производных классов, так что catch производного класса никогда не будет выполняться. Иногда программа может обрабатывать многие близко связанные типы исключений. Вместо того, чтобы обеспечивать каждое исключение отдельным классом и обработчиком catch, программист может создать один класс исключения и один обработчик catch для группы исключений. При возникновении каждого из таких исключений может создаваться один объект исключения с различными закрытыми данными. Обработчик catch может просматривать эти закрытые данные, чтобы различить типы исключений. Как фиксируется соответствие типа? Тип параметра в заголовке catch соответствует типу сгенерированного объекта, если: они имеют действительно одинаковый тип; тип параметра обработчика catch является открытым базовым классом класса сгенерированного объекта; параметр обработчика имеет тип указатель и сгенерированный объект тоже имеет тип указатель, преобразуемый в тип параметра путем допустимых преобразований указателей. Например, указатель производного класса преобразуется в указатель базового класса стандартными операциями преобразования; обработчик catch записан в форме catch (...). Замечание по технике программирования 13.9 Самое лучшее - включить вашу стратегию обработки исключений в проектируемую систему до начала процесса проектирования. Трудно добавлять эффективную обработку исключений после того, как система реализована. Если блок try не генерирует никаких исключений, то после завершения нормального выполнения блока try управление передается первому оператору после последнего обработчика catch, следующего за этим блоком try. Невозможно возвратиться к точке генерации исключения, используя оператор return в обработчике catch. Такой оператор return просто вернет управление в ту функцию, которая вызывала функцию, содержащую данный блок catch. Можно сгенерировать объекты исключений const и volatile. В этом случае тип параметра обработчика catch также должен быть объявлен как const или volatile соответственно. По умолчанию, если никакой обработчик для исключения не найден, программа завершается. Хотя это может показаться оправданным, программисты не обязаны этому следовать. Чаще при возникновении ошибки продолжается выполнение программы, возможно только несколько прихрамывающее . Обработчики исключений, следующие за блоком try, напоминают оператор switch. Интересно, что в данном случае нет необходимости использовать break, чтобы выйти из обработчика, пропуская остающиеся обработчики исключений. Каждый блок catch определяет отличную от других область действия, в то время как все случаи в операторе switch находятся внутри общей области действия этой структуры. Исключение не имеет доступа к объектам, описанным внутри блока try, потому что они уже удалены в результате разматывания стека к тому моменту, когда обработчик начинает выполняться (см. раздел 13.13). Что происходит, когда исключение возникает в обработчике исключения? Первоначальное исключение, которое было перехвачено, формально считается обработанным в тот момент, когда начинает выполняться обработчик исключения. Так что исключения, возникающие в обработчике, должны обрабатываться вне того блока try, в котором было сгенерировано первоначальное исключение. Обработчики исключений могут быть написаны различными способами. Они могут рассмотреть ошибку и решить вызвать функцию terminate. Они могут просто повторно сгенерировать исключение (см. раздел 13.9). Они могут преобразовать один тип исключения в другой, генерируя это другое исключение. Они могут выполнить любые необходимые восстановления и продолжить выполнение с первого оператора после последнего обработчика исключения. Они могут рассмотреть ситуацию, вызвавшую ошибку, удалить причину ошибки и повторить вызов первоначальной функции, которая вызвала исключение (это не должно создавать бесконечную рекурсию). Они могут просто возвращать некоторое значение состояния в среду и т.д. Замечание по технике программирования 13.10 Еще одна причина, по которой нецелесообразно использовать исключения для обычного потока управления, заключается в том, что эти дополнительные исключения могут попадаться на пути подлинных исключений, связанных с ошибками. Поэтому программисту становится труднее следить за большим числом исключений. Например, когда программа обрабатывает чрезмерное разнообразие исключений, можно ли бьпь действительно уверенным в том, какое из них перехватывается обработчиком catch (...)? Исключительные ситуации должны бьпь редкими, а не встречаться постоянно. Важна последовательность обработчиков catch. Обработчики, которые перехватывают объекты производных классов, должны быть помещены перед обработчиками, которые перехватывают объекты базового класса; иначе, обработчик базового класса перехватит как объекты самого базового класса, так и объекты всех производных классов. Когда исключение перехвачено, возможно, что ресурсы, которые были выделены, еще не освобождены в блоке try. Обработчик catch, если возможно, должен высвободить эти ресурсы. Например, обработчик catch должен освободить область памяти, выделенную операцией new, должен закрыть любые файлы, открытые в блоке try, сгенерировавшем исключение. Автоматические объекты разрушаются в результате разматывания стека прежде, чем обработчик начнет выполняться. Блок catch может обрабатывать ошибку способом, который дает возможность программе продолжать выполняться правильно. Или блок catch может завершить программу. Обработчик catch непосредственно сам может обнаружить ошибку и сгенерировать исключение. Подобное исключение не будет обработано обработчиками catch, связанными с тем же самым блоком try, что и обработчик, сгенерировавший исключение. Это исключение будет перехвачено, если возможно, обработчиком, связанным со следующим внешним блоком try. Типичная ошибка программирования 13.9 Предположение, что исключение, сгенерированное обработчиком catch, будет обработано этим или любым другим обработчиком, связанным с тем же блоком try, который сгенерировал первоначальное исключение. 13.9. Повторная генерация исключений Возможно, что обработчик, который перехватил исключение, решит, что он не может обработать это исключение, или может просто потребоваться освободить ресурсы прежде, чем проводить дальнейшую обработку. В этом случае обработчик может просто повторно сгенерировать это исключение оператором throw; Такой оператор throw без аргументов повторно генерирует то же самое исключение. Если никакое исключение не было сгенерировано, то оператор повторной генерации вызывает обращение к функции завершения terminate. Поэтому оператор throw должен появляться только в обработчике catch; в противном случае, он вызовет обращение к terminate.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |