Стандарты программирования на С++

Пространства имен и модули


57.Храните типы и их свободный интерфейс в одном пространстве имен

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

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

Оберегайте ваши типы от непреднамеренного поиска, зависящего от аргументов (argument-dependent lookup — ADL, известный также как поиск Кёнига); однако преднамеренный поиск должен завершаться успешно. Этого можно добиться путем размещения типов в своих собственных пространствах имен (вместе с непосредственно связанными с ними свободными функциями; см. рекомендацию 57). Избегайте помещения типов в те же пространства имен, что и шаблоны функций или операторов).

59. Не используйте using для пространств имен в заголовочных файлах или перед директивой #include

Директива using для пространств имен создана для вашего удобства, а не для головной боли других. Никогда не используйте объявления или директивы using перед директивой #include.

Вывод: не используйте директивы using для пространств имен или using-объявления в заголовочных файлах. Вместо этого полностью квалифицируйте все имена. (Второе правило следует из первого, поскольку заголовочные файлы не могут знать, какие другие директивы #include могут появиться в тексте после них.)

60. Избегайте выделения и освобождения памяти в разных модулях

Золотое правило программиста — положи, где взял. Выделение памяти в одном модуле, а освобождение в другом делает программу более хрупкой, создавая тонкую дальнюю зависимость между этими модулями. Такие модули должны быть компилируемы одной и той же версией компилятора с одними и теми оке флагами (в частности, отладочные версии и версии NDEBUG) и с одной и той же реализацией стандартной библиотеки; кроме того, с практической точки зрения лучше, чтобы модуль, выделяющий память, оставался загружен при ее освобождении.


61. Не определяйте в заголовочном файле объекты со связыванием

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

62. Не позволяйте исключениям пересекать границы модулей

Не бросайте камни в соседский огород — поскольку нет повсеместно распространенного бинарного стандарта для обработки исключений C++, не позволяйте исключениям пересекать распространяться между двумя частями кода, если только вы не в состоянии контролировать, каким компилятором и с какими опциями скомпилированы обе эти части кода. В противном случае может оказаться, что модули не поддерживают совместимые реализации распространения исключений. Обычно это правило сводится к следующему: не позволяйте исключениям пересекать границы модулей/подсистем.

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

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

Стр.214


Содержание раздела