重複の可能性:
C++ で「インクルード」を配置する場所
#include
明らかに、ディレクティブを C++ ヘッダー ファイルに配置するかどうか (または、代わり#include
に cpp ファイルのみに配置するか) については、2 つの "考え方" があります。大丈夫だと言う人もいれば、問題を引き起こすだけだと言う人もいます。この議論が何を優先すべきかという結論に達したかどうか、誰か知っていますか?
重複の可能性:
C++ で「インクルード」を配置する場所
#include
明らかに、ディレクティブを C++ ヘッダー ファイルに配置するかどうか (または、代わり#include
に cpp ファイルのみに配置するか) については、2 つの "考え方" があります。大丈夫だと言う人もいれば、問題を引き起こすだけだと言う人もいます。この議論が何を優先すべきかという結論に達したかどうか、誰か知っていますか?
私はこれに関する思想の学校を知りません。それらが必要な場合はヘッダーに入れます。それ以外の場合は、前方宣言して、それら.cpp
を必要とするファイルに入れます。必要のないヘッダーを含めるメリットはありません。
私が効果的だと思ったのは、いくつかの簡単なルールに従うことです。
最初のポイントを取得するのはかなり簡単です。ヘッダーが宣言する内容を実装するソースから最初にヘッダーをインクルードします。ただし、2 番目の点を正確に把握することは簡単ではなく、正確に把握するにはツールのサポートが必要だと思います。ただし、いくつかの不必要な依存関係は、通常、それほど悪くはありません。
経験則として、ヘッダーの完全な定義が必要である限り、ヘッダーにヘッダーを含めません。ほとんどの場合、ヘッダー ファイル内のクラスのポインターを操作するので、ヘッダー ファイルでそれらを前方宣言しても問題ありません。
これらは宗教ほどの思想の学校ではありません。実際には、どちらのアプローチにも長所と短所があり、どちらのアプローチを成功させるためにも従うべき特定の慣行があります。しかし、これらのアプローチの1つだけが、大規模なプロジェクトに「拡張」します。
ヘッダー内にヘッダーを含めないことの利点は、コンパイルが高速になることです。ただし、この利点は、ヘッダーが1回だけ読み取られることによるものではありません。これは、ヘッダー内にヘッダーを含めた場合でも、スマートコンパイラーがそれを解決できるためです。速度の利点は、特定のソースファイルに厳密に必要なヘッダーのみを含めるという事実にあります。もう1つの利点は、ソースファイルを見ると、その依存関係が正確にわかることです。ヘッダーファイルのフラットリストは、それを明確に示しています。
ただし、特に多くのプログラマーがいる大規模なプロジェクトでは、この方法を維持するのは困難です。モジュールを使用する場合は非常に不便ですが、35個の他のヘッダーを含める必要があるfoo
だけではありません。#include "foo.h"
最終的に発生するのはこれです。プログラマーは、モジュールを追加するためだけに必要な、正確で最小限のヘッダーのセットを見つけるために時間を無駄にすることはありませんfoo
。#include
時間を節約するために、作業中のものと同様のサンプルソースファイルに移動し、すべてのディレクティブをカットアンドペーストします。それから彼らはそれをコンパイルしようとします、そしてそれが構築されないなら、彼らは#include
まだ他の場所からさらに多くのディレクティブをカットアンドペーストし、それが機能するまでそれを繰り返します。
最終的な結果として、ファイルに不要なヘッダーが含まれるようになったため、コンパイルが高速になるという利点が少しずつ失われます。さらに、#include
ディレクティブのリストに実際の依存関係が表示されなくなりました。さらに、ここでインクリメンタルコンパイルを実行すると、これらの誤った依存関係のために必要以上にコンパイルされます。
すべてのソースファイルにほぼすべてのヘッダーが含まれている場合は、everything.h
すべてのヘッダーを含む大きなファイルを作成し、次に#include "everything.h"
すべてのソースファイルを作成することもできます。
したがって、特定のヘッダーのみを含めるというこの方法は、最小限のインクルード依存関係を手作業で維持する、または不要な#include
ディレクティブを探すためのツールを作成するための十分な時間を持っている少数の開発者によって慎重に維持される小さなプロジェクトに任せるのが最善です。
問題はずっと前に解決されたと思います: ヘッダーは自己完結型である必要があります (つまり、ユーザーが以前に他のヘッダーを含めたことに依存するべきではありません。これについての議論ですが、あなたのプットインクルードは.cppにのみ含まれているようです)が最小限です(つまり、宣言が自己完結に十分な場合は定義を含めるべきではありません)。
自己完結型の理由はメンテナンスです。ヘッダーが変更され、新しいものに依存するようになった場合、新しい依存関係を含めるために使用されているすべての場所を追跡する必要があります。ところで、自己完結型を確保するための標準的なトリックは、.cpp で最初に .cpp で定義されたものの宣言を提供するヘッダーを含めることです。