Стандарты программирования на С++. 101 правило и рекомендация | страница 45
Однако не включайте заголовочные файлы, в которых вы не нуждаетесь, так как это напрасно создает паразитные зависимости.
Для гарантии самодостаточности заголовочных файлов скомпилируйте каждый из них отдельно от других и убедитесь, что это не приводит к ошибкам или предупреждениям.
Ряд тонких моментов возникает в связи с использованием шаблонов.
Пример 1. Зависимые имена. Шаблоны компилируются в точке, где они определены, с тем исключением, что все зависимые имена или типы не компилируются до точки инстанцирования. Это означает, что >template
с членом >std::deque
не приведет к ошибке времени компиляции, даже если заголовочный файл >
не включен — если при этом не происходит инстанцирование >Widget
. Поскольку очевидно, что шаблон >Widget
существует для того, чтобы быть инстанцированным, его заголовочный файл должен содержать строку >#include
.
Пример 2. Шаблоны функций-членов и функции-члены шаблонов инстанцируются только при использовании. Предположим, что >Widget
не имеет члена типа >std::deque
, но функция-член >Widget
с именем >Transmogrify
использует >deque
. Тогда вызывающая >Widget
функция может инстанцировать и использовать >Widget
, даже если заголовочный файл >
не включен — до тех пор, пока не используется функция-член >Transmogrify
. По умолчанию заголовочный файл >Widget
все же должен включать >
, поскольку это необходимо, по крайней мере, для некоторых пользователей >Widget
. В редких случаях, когда большой заголовочный файл включается только для обеспечения работоспособности нескольких редко используемых функций шаблона, следует подумать о том, чтобы сделать эти функции не членами и вынести их в отдельный заголовочный файл, включающий упомянутый большой файл (см. рекомендацию 44).
[Lakos96] §3.2 • [Stroustrup00] §9.2.3 • [Sutter00] §26-30 • [Vandevoorde03] §9-10
24. Используйте только внутреннюю, но не внешнюю защиту директивы >#include
Предотвращайте непреднамеренное множественное включение ваших заголовочных файлов директивой >#include
, используя в них защиту с уникальными именами.
Каждый заголовочный файл должен использовать внутреннюю защиту директивы >#include
, чтобы предотвратить переопределения в случае множественного включения данного файла. Например, заголовочный файл >fоо.h
должен иметь такой общий вид:
>#ifndef FOO_H_INCLUDED_
>#define FOO_H_INCLUDED_
>// ... Содержимое файла …
>#endif
Обратите внимание на следующие правила при определении защиты включения.