Стандарты программирования на С++. 101 правило и рекомендация | страница 110



последовательностью перехватов >catch(E1&){/*...*/} catch(E2&){/*.. .*/} ... catch(En&){/*...*/} для всех известных типов базовых исключений >Ei масштабируемым решением не является, поскольку вам придется обновлять этот список при добавлении новых библиотек (использующих собственные иерархии исключении) в ваше приложение.

Использование >catch(...) в других, не перечисленных в данной рекомендации местах зачастую является признаком плохого проектирования, поскольку означает, что вы хотите перехватить абсолютно все исключения без обязательного знания о том, как следует обрабатывать конкретные исключения (см. рекомендацию 74). В хорошей программе не так много перехватов всех исключений, да и вообще инструкций try/catch; в идеале ошибки распространяются через весь модуль, транслируются на его границе (неизбежное зло) и обрабатываются в стратегически размещенных местах.

Ссылки

[Stroustrup00] §3.7.2, §14.7 • [Sutter00] §8-17 • [Sutter02] §17-23 • [Sutter04] §11-13

63. Используйте достаточно переносимые типы в интерфейсах модулей

Резюме

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

Обсуждение

Чем более широко распространяется ваша библиотека, тем меньше ваш контроль над средами программирования, используемыми вашими клиентами, и тем меньше множество типов, которые ваша библиотека может надежно использовать в своем внешнем интерфейсе. Взаимодействие между модулями включает обмен бинарными данными. Увы, С++ не определяет стандартные бинарные интерфейсы; широко распространенные библиотеки для взаимодействия со внешним миром могут полагаться на такие встроенные типы, как >int и >char. Даже один и тот же тип на одном и том же компиляторе может оказаться бинарно несовместимым при компиляции с разными опциями.

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