Это один из тех стандартов кодирования, которые «должны», а не «должны». Причина в том, что вам пришлось бы написать синтаксический анализатор C ++ для его принудительного применения.
Очень распространенным правилом для заголовочных файлов является то, что они должны стоять самостоятельно. Заголовочный файл не должен требовать, чтобы некоторые другие заголовочные файлы были #included перед включением соответствующего заголовка. Это проверяемое требование. Учитывая некоторый случайный заголовок foo.hh
, следующее должно скомпилироваться и выполнить:
#include "foo.hh"
int main () {
return 0;
}
Это правило имеет последствия в отношении использования других классов в некотором заголовке. Иногда этих последствий можно избежать, объявив другие классы вперёд. Это невозможно с большим количеством стандартных библиотечных классов. Нет способа переслать объявление экземпляра шаблона, например std::string
или std::vector<SomeType>
. Вы должны использовать #include
эти заголовки STL в заголовке, даже если тип используется только в качестве аргумента функции.
Другая проблема связана с вещами, которые вы случайно перетаскиваете. Пример: рассмотрите следующее:
файл foo.cc:
#include "foo.hh"
#include "bar.hh"
void Foo::Foo () : bar() { /* body elided */ }
void Foo::do_something (int item) {
...
bar.add_item (item);
...
}
Вот bar
член класса Foo
данных, который имеет тип Bar
. Вы сделали все правильно, и у вас есть #included bar.hh, хотя это должно было быть включено в заголовок, который определяет класс Foo
. Тем не менее, вы не включили материал, используемый Bar::Bar()
и Bar::add_item(int)
. Во многих случаях эти вызовы могут привести к дополнительным внешним ссылкам.
Если вы проанализируете foo.o
с помощью такого инструмента, как nm
, то окажется, что функции foo.cc
вызывают все виды вещей, для которых вы не сделали соответствующего #include
. Так что вы должны добавить #include
директивы для этих внешних ссылок foo.cc
? Ответ абсолютно нет. Проблема в том, что очень трудно отличить те функции, которые вызываются случайно, от тех, которые вызываются напрямую.