|
Программирование >> Обобщенные обратные вызовы
Вопросы и приемы безопасности исключений Обработка исключений представляет собой фундаментальный механизм сообщения об ошибках в совремснных языках программирования, включая С++. В [SutterOO] и [Sultcrt)2] мы детально рассмотрели множество вопросов, связанных с определением того, что такое безопасность исключений, как следует писать безопасный с точки зрения исключений код и многие другие. В .этом разделе мы продолжим изложение материала, посвященного обработке исключений, сконцентрировав свое внимание на некоторых специфических возможностях языка, связанных с исключениями. Начнем же мы с ответов на неизменные вопросы - достаточно ли для безопасности исключений написать в нужном месте try и catch? Если нет, то что для этого требуется? И о чем не следует забывать при разработке стратегии безопасности исключений в ваших программах? Прежде всего, одну задачу мы посвятим выяснению причин, по которым так важно написание безопасного с точки зрения исключений кода. Это позволит выработать стиль программирования, который даст воз.можность писать более интеллектуальный, надежный и легко сопровождаемый код - даже безотносительно обработки исключений. Однако не следует забывать, что лучшее - враг хорошего, и мы сможем убедиться в этом еще раз при рассмотрении спецификаций исключений. Мы рассмотрим целый ряд вопросов. Зачем они нужны в языке? Насколько оправданно было их введение в язык в принципе? Почему, несмотря на их наличие, лучше не использовать их в своих программах? Задача 11. Попробуй поймай Сложность: 3 Заключается ли безопасность исключений в том, чтобы написать try и catch в нужном месте? Если нет, то в чем? О чем не следует забывать при разработке стратегии безопасности исключений в ваших программах? Вопрос для новичка 1. Что такое try-блок? Вопрос для профессионала 2. Написание безопасного с точки зрения исключений кода сводится в целом к размещению try и catch в правильных местах . Обсудите это утверждение. 3. Когда следует использовать try и catch? Когда их не следует использовать? Изложите ваш ответ в виде рекомендации стандарта кодирования. Решение 1. Что такое try-блок? try-блок (в некоторых книгах - блок с контролем ) представляет собой блок кода (составную инструкцию), выполнение которого может быть неудачным (приводящим к генерации исключения), за которым следует один или несколько блоков обработки исключений, которые выполняются при генерации в основном блоке исключения определенного типа, например: Пример 11-1: пример try-блока try { if( не которое условие ) throw stringC Строка ); else if(некоторое иное условие ) throw 42; catch( const string* ) { Выполняется при генерации исключения, имеющего тип stri ng catchC ... ) { Выполняется при генерации любого другого исключения В примере 11-1 код в основном блоке может сгенерировать исключение типа string, int или не сгенерировать никакого исключения. 2. Написание безопасного с точки зрения исключений кода сводится в целом к размещению try и catch в правильных местах . Обсудите это утверждение. Честно говоря, такое утверждение отражает фундаментальное непонимание безопасности исключений. Исключения представляют собой один из видов сообщения об ошибках, и мы знаем, что написание устойчивого к ошибкам исходного текста не сводится к проверке кода возврата и обработке ошибки. В оригинале - ифа слов, основанная на переводе ключевых слов try - пробовать, и catch - ловить. - Прим. перев. в действительности, безопасность исключений редко сводится к написанию ключевых слов (и чем меньше вы их пишете, тем лучше). Никогда нельзя забывать о том, что безопасность исключений влияет на проектирование. Вопросы безопасности надо учитывать заранее, еще на стадии проектирования програм.мы, а не просто расставлять ключевые слова в подходящих местах. Вот три основных момента, которые надо учитывать при написании безопасного в смысле исключений кода. 1. Где и когда следует генерировать исключения? Это вопрос о том, где именно следует размещать инструкции throw. В частности, мы должны ответить на следующие вопросы. Какие именно исключения должен генерировать код? То есть о каких ошибках мы будем сообщать при помощи механизма исключений, а не при помощи возврата кода ошибки или какого-либо иного метода? Какой код не должен генерировать исключений? В частности, какой код гарантирует отсутствие исключений? (См. задачу 12 и [Sutter99].) 2. Где и когда следует обрабатывать исключения? Эт единственный юпрос, связанный с выбором правильного размещения try и catch, и в большинстве случаев эта проблема решается автоматически. Начнем с вопросов, на которые мы должны ответить. Какая часть исходного текста должна отвечать за обработку исключений? То есть у какого кода оказывается достаточно контекста и информации для обработки ошибки, о которой сообщается посредством исключения (возможно, путем преобразования исключения к другому виду)? В частности, заметим, что код обработчика должен обладать информацией, достаточной для того, чтобы выполнить все необходимые действия по освобождению распределенных ресурсов. Какой код должен обрабатывать исключения? То есть каким образом выбрать среди всех возможных вариантов размещения кода обработчика наиболее подходящий? После того как мы ответим на эти вопросы, отметим, что использование идиомы распределение ресурса есть инициализация зачастую позволяет избежать использования ряда try-блоков путем автоматизации работы по освобождению ресурсов. Если вы обернете динамически распределяемые ресурсы в объект-владелец, его деструктор обычно в состоянии выполнить аетоматическое освобождение распределенного ресурса в необходимый момент времени, без явного использования try и catch, не говоря о том, что код с использованием этого метода проще писать, а позже - читать и понимать. > Рекомендация Использование автоматического освобождения с помощью деструкторов предпочтительнее применения для этой цели try-блоков. 3. Будет ли поведение моего кода безопасным, если произойдет генерация исключения в какой-либо из вызываемых функций? Это - вопрос правильного управления ресурсами, позволяющего избежать утечек, содержания классов и инвариантов программы в должном порядке и прочих показателей корректности программы. Иначе говоря, надо, чтобы в случае генерации исключения до его перехвата и обработки программа оставалась работоспособной, в согласованном состоянии, и могла продолжить работу после обработки исключения. Для большинства программистов именно этот аспект безопасности исключений представляет наибольшую сложность и требует наибольших усилий при написании кода. Заметим, что среди трех перечисленных моментов только один непосредственно связан с размещением ключевых слов try и catch, да и тех часто можно избежать
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |