Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [ 26 ] 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

разработки -- из-за повышения степени связности. Например, удалив один тип из списка в спецификации исключений виртуальной функции базового класса, мы заставим компилятор ругаться на перекрытия этой функции в производных классах (разработкой которых занимались ваши коллеги). Попробуйте сделать это как-нибудь вечером в пятницу, а в понедельник утром посчитайте количество гневных писем, пришедших вам по электронной почте.

В связи с эти вполне логичным представляегся следующий вопрос.

5. Когда стоит использовать спецификацию исключений в функции? Почему вы используете (или не используете) эту возможность?

Вот, пожалуй, наилучшие советы, рожденные опытом всего сообщества программистов на С++.

> Рекомендация

Совет №1. Никогда не указывайте спецификации исключений.

Совет №2. Возможное исключение из совета №1 - это пустая спецификация исключений, но на вашем месте я бы избегал и ее.

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

На практике все еще хуже, поскольку оказывается, что распространенные реализации С++ ухитряются по-разному обрабатывать спецификации исключений. Как минимум один популярный компилятор С++ (Microsoft - до текущей на момент написания эгой задачи версии 7.1 (2003)) выполняет синтаксический анализ спецификаций исключений, но в действительности не учитывает их в работе, превращая их по сути в некоторое подобие комментариев. Но это еще не все. Например, оптимизация, которую выполняет компилятор Microsoft С++ 7.x, полагается на то, что спецификация исключений будет обеспечена внутри функции. Идея заключается в том, что если функция попытается сгенерировать нечто запретное, то внутренний обработчик остановит выполнение профаммы и управление никогда не вернется вызывающей функции. Так что если контроль возвращается вызывающей функции, то можно считать, что генерации исключений не было, а значит, в этом случае можно вообще убрать внешние try/catch-блоки.

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

Резюме

Коротко: не утруждайте себя написанием спецификаций исключений. Более подробно:

• Спецификации исключений могут привести к неожиданному изменению производительности программы, например, если компилятор не делает функции со спецификациями исключений встраиваемыми.



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

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

Когда данный материал не так давно был представлен мною на конференции, я спросил, кто из присутствующих использовал в своей практике спецификации исключений. Утвердительно ответила половина слушателей. Тогда один из слушателей сказал, что мне надо было бы спросить, сколько из этих людей теперь откажутся от них, что я и сделал. И поднялось примерно то же количество рук. Это весьма показательно. Разработчики библиотеки Boost, программисты мирового класса, имеющие большой опыт работы со спецификациями исключений, наилучшей стратегией считают отказ от этой возможности [ Boost ES).

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

Будьте умеренны в своих желаниях - ведь вы можете получить то, что просите!



Разработка классов, наследование и полиморфизм

Помимо парадигмы обобщенного программирования, С++ поддерживает объектно-ориентированное проектирование и программирование. В этом разделе мы обратимся к этой более тралиииоииой области, уделив основное внимание объектно-ориентированным возможностям С+ + .

Мы начнем с примера реального кода, в котором есть один тонкий изъян, и используем его в качестве трамплина для обзора порядка конструирования и деструкции объектов.

Затем мы обратимся к вопросам создания надежного кода, которые пересекаются с вопросами безопасности. Какая часть класса доступна из другого кода? Как осуществить "утечку" закрытой части класса, причем не столь важно, непреднамеренно или специально? Что такое инкапсуляция и как она соотносится с выбором прав доступа к членам? Наконец, как сделать наши классы более удобными с точки зрения управления версиями, а также с легко поддерживаемым интерфейсом, который не может быть случайно или преднамеренно разрушен в порожденных классах, что могло бы привести к неработоспособности и брешам в системе безопасности?

Итак, погрузимся в море классов и объектов...



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [ 26 ] 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85