これは、「Shall」ではなく、「すべき」コーディング標準の1つです。その理由は、それを強制するためにC ++パーサーを作成する必要があるからです。
ヘッダーファイルの非常に一般的なルールは、ヘッダーファイルが独立している必要があることです。ヘッダーファイルでは、問題のヘッダーをインクルードする前に、他の一部のヘッダーファイルを#includeする必要はありません。これはテスト可能な要件です。いくつかのランダムなヘッダーfoo.hh
を指定すると、次のコードがコンパイルされて実行されます。
#include "foo.hh"
int main () {
return 0;
}
このルールは、一部のヘッダーでの他のクラスの使用に関して影響を及ぼします。これらの他のクラスを前方宣言することにより、これらの結果を回避できる場合があります。これは、多くの標準ライブラリクラスでは不可能です。std::string
またはなどのテンプレートのインスタンス化を転送宣言する方法はありませんstd::vector<SomeType>
。あなたはに持っている#include
タイプの使用のみが関数の引数としてであっても、ヘッダーのものSTLヘッダ。
もう1つの問題は、偶発的にドラッグしたものです。例:次のことを考慮してください。
ファイル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
。あなたはここで正しいことを行い、それがclassを定義するヘッダーに含まれていなければならなかったとしても#included bar.hhを持っていFoo
ます。ただし、Bar::Bar()
およびで使用されるものは含まれていませんBar::add_item(int)
。これらの呼び出しにより、追加の外部参照が発生する可能性がある多くの場合があります。
foo.o
などのツールで分析すると、nm
の関数foo.cc
が、適切な処理を行っていないあらゆる種類の機能を呼び出しているように見えます#include
。では#include
、これらの偶発的な外部参照のディレクティブを追加する必要がありますfoo.cc
か?答えは絶対にありません。問題は、偶発的に呼び出される関数と直接呼び出される関数を区別するのが非常に難しいことです。