Це один із тих типів стандартів кодування "повинен", а не "повинен". Причина полягає в тому, що вам досить доведеться написати аналізатор 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? Відповідь абсолютно ні. Проблема полягає в тому, що дуже важко відрізнити ті функції, які викликаються випадково, від тих, які викликаються безпосередньо.