Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.
これをここで読みました。 http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html 。
したがって、ヘッダーファイル内のクラス(クラスA)が一部のクラス(クラスB)の実際の定義を使用する必要がないかどうかを示します。現時点では、特定の(クラスB)ヘッダーファイルをインクルードする代わりに、フォワード宣言を使用できます。
質問:ヘッダー内のクラス(クラスA)が特定のクラス(クラスB)の実際の定義を使用しない場合、前方宣言はコンパイル時間をどのように短縮するのに役立ちますか?
コンパイラーは、クラスAがクラスBを使用するかどうかを考慮しません。クラスAがコンパイルされ、クラスBの事前宣言(前方宣言など)がない場合にのみパニックになり、エラーとしてマークします。
ここで重要なのは、猫がキーボードの上を歩き、クラスとして解釈される場合と解釈されない場合があるランダムな文字を作成した後で、コンパイラーがプログラムをコンパイルしようとしなかったことを知っていることです。
インクルードが見つかると、その中に含まれている情報を使用できるようにするために、ファイルを開いて解析する必要があります(実際にそうする必要があるかどうかに関係なく)。そのファイルに他のファイルが含まれている場合は、それらも開いて解析する必要があります。これを回避できる場合は、代わりに前方宣言を使用することをお勧めします。
編集:プリコンパイル済みヘッダーであるこのルールの例外。この場合、すべてのヘッダーがコンパイルされ、将来のコンパイルのために保存されます。ヘッダーが変更されない場合、コンパイラーは以前のコンパイルのプリコンパイル済みヘッダーをスマートに使用できるため、コンパイル時間を短縮できますが、ヘッダーを頻繁に変更する必要がない場合にのみ機能します。
なぜなら、A.hppは#include B.hppを必要としないからです。
a.hppは
class B;//or however forward decl works for classes
class A
{
B* bInstance_;
//...
}
したがって、A.hppが含まれている場合、B.hppは暗黙的に含まれず、A.hppのみに依存するすべてのファイルは、b.hppが変更されるたびに再コンパイルする必要はありません。
C/C++プリプロセッサーは、別個の純粋なテキストによる処理ステップであることを忘れないでください。 #include
ディレクティブはインクルードされたヘッダーのコンテンツを取り込み、コンパイラーはそれを解析する必要があります。さらに、各.cpp
のコンパイルは完全に分離されているため、B.h
のコンパイル時にコンパイラがB.cpp
を解析しただけでは、A.cpp
のコンパイル時に再度必要になったときに、ほとんど役に立ちません。そして再びC.cpp
をコンパイルするとき。そして、D.cpp
。等々。そして、含まれているファイルが変更された場合、それらの各ファイルを再コンパイルする必要があります。
したがって、クラスA
はクラスB
を使用し、クラスC
およびD
はクラスA
を使用しますが、B
を操作する必要はありません。 A
の前方宣言だけでクラスB
を宣言できる場合、B.h
は2回コンパイルされます:B.cpp
とA.cpp
をコンパイルするとき(B
のメソッド内でA
がまだ必要なため)。
ただし、A.h
にB.h
が含まれている場合は、コンパイルされますfour回—B.cpp
、A.cpp
、C.cpp
およびD.cpp
をコンパイルするとき、後者の2つは間接的にB.h
も含むようになりました。
また、ヘッダーが複数含まれている場合でも、プリプロセッサはそれを読み取る必要がありますeach時間。ガード#ifdef
sがあるため、コンテンツの処理をスキップしますが、それでも読み取りとガードの終了を検索する必要があります。つまり、内部のすべてのプリプロセッサディレクティブを解析する必要があります。
(他の回答で述べたように、プリコンパイル済みヘッダーはこれを回避するための試みですが、それらは独自のワームの缶です;基本的にそれらをシステムヘッダーに合理的に使用でき、それらの多くを使用していない場合のみプロジェクトのヘッダー)
前方宣言は、それ自体がさらに多くのヘッダーファイルを含む可能性があるヘッダーファイル全体よりも、解析がはるかに高速です。
また、クラスBのヘッダーファイルで何かを変更した場合、そのヘッダーを含むすべてを再コンパイルする必要があります。前方宣言を使用すると、それはAの実装が存在するソースファイルだけになる可能性があります。ただし、Aのヘッダーに実際にBのヘッダーが含まれている場合、a.hpp
は、Bを何も使用していなくても、再コンパイルされます。