X
3つのプロジェクト、、、Y
およびのソリューションがあるとしE
ます。
E
実行可能ファイルを生成しX
、のヘッダーファイルをインクルードし、のヘッダーファイルをインクルードするようなY
静的ライブラリを生成します。Y
X
E
Y
さて、私の質問は、なぜヘッダーファイルのディレクトリをにインクルードする必要があるのかということX
ですE
。
X
3つのプロジェクト、、、Y
およびのソリューションがあるとしE
ます。
E
実行可能ファイルを生成しX
、のヘッダーファイルをインクルードし、のヘッダーファイルをインクルードするようなY
静的ライブラリを生成します。Y
X
E
Y
さて、私の質問は、なぜヘッダーファイルのディレクトリをにインクルードする必要があるのかということX
ですE
。
理由は次のとおりです。
Y
で宣言された型の引数を取る(または値を返す)可能性がありますX
。E
。X
は絶対に必要ですE
。説明する状況を回避するために、C++のヘッダーファイルを再構築して前方宣言を使用できる場合があります。次に例を示します。C++ヘッダーの依存関係のトリック。
簡単なケース:
class X {
//...
};
// #include <X.h> -- remove this
class X; // add forward declaration
class Y {
X *m_px; // must be a pointer, not a value,
// otherwise the size of X would need to be known
//...
};
#include <X.h> // need to add it here
//...
Xへの依存関係が完全にカプセル化されるようにYを構築すると、この状況を回避できます。これは、XとYの詳細に応じて可能な場合と不可能な場合があります。ただし、YがEに提示するインターフェイスにXの詳細を含める必要がない場合、Eプロジェクトに間接的に含める必要はありません。 Xからのヘッダー。シンの場合、Yの実装ファイル(.cまたは.cppファイル)のみにXからのヘッダーが含まれます。YヘッダーでXの型に前方宣言を使用すると、YでのXのカプセル化を実現できます。
これは達成するための良い目標ですが、常に可能であるとは限らず、可能である場合でも、あなた(またはあなたの経営陣)が出したいよりも多くの努力が必要になる場合があります。
簡単な答え:「XのヘッダーファイルのディレクトリをEにインクルードする必要があるのはなぜですか?」...すべきではありません。Yのクライアントは、YがXに依存していることを知る必要はありません。
長い答え: Yのインターフェイス(署名)がXのヘッダーで宣言されたものを使用する場合にのみ、XのヘッダーをEに含める必要があります。ただし、Yのヘッダーが「適切に構築された」場合は、 Yヘッダー自体にXのヘッダーが含まれているため、EにXヘッダーを明示的に含める必要はありません(Yヘッダーを含めると自動的にXヘッダーが含まれます)。
「適切に構築された」とは、YのY1.hの署名が(たとえば)X3.hとX7.hに依存している場合、Y1.hにそれらのファイルを(直接的または間接的に)含める必要があることを意味します。このように、Y1.hのクライアントは、依存関係が何であるかを知る必要がなく、結果としてそれらの依存関係を個別に含める必要があります。簡単なテストとして、次の行で構成される.cppは問題なくコンパイルされるはずです。
#include "Y1.h"
Y1.cppに他のファイルを含める前に、「Y1.h」を#includeすることをお勧めします。Y1.hに依存関係がない場合、コンパイラーは通知します。