円形の包含を作成しましたD1.h
。D2.h
に含め、またに含めD2.h
ましたD1.h
。循環包含は機能せず、何も達成しません。
循環包含は、クラス定義間の循環依存の直接的な結果です。コードでは、両方のクラス定義が、両方のクラスタイプが完全である(完全に定義されている)必要がある方法で相互に参照しています。つまり、何をしても、コードをそのままコンパイルすることはできません。クラス定義間の循環依存を解消する必要があります。
あなたの場合、それは次の方法で行うことができます。
変更しないでください。つまり、クラスの定義をD1.h
そのまま含めD2.h
て保持します。D1.h
D1
ただし、に含めないでください。代わりに、の前方宣言を導入してください。D1.h
D2.h
D1
D2.h
class D1;
の定義をD2
に変更します
class D2: public B {
public:
int get(D1& d);
};
get
注:クラスの定義でメソッドを正しく定義しようとしないでくださいD2
。の定義を他の場所に再配置する必要があります。ここでは、の完全な定義も表示されます(たとえば、との両方を含める必要があります)。D2::get
D1
D2.cpp
D1.h
D2.h
int D2::get(D1& d)
{
return d.a;
}
それでおしまい。この方法を定義することの副作用D2::get
は、それが非インラインになることです。本当にインラインにしておきたい場合は、次のように定義する必要があります。
inline int D2::get(D1& d)
{
return d.a;
}
また、の完全な定義の後にのみ、何らかの形で含まれていることを確認してくださいD1
。たとえば、3番目のヘッダーファイル(D2_aux.h
またはそのようなもの)に配置し、の後にインクルードすることを忘れないでD1.h
ください。
もちろん、この問題を解決するためのより良い方法は、設計全体を再考することです。あなたは本当にその友達宣言が必要D1
ですか?たぶん、そのフレンド宣言の必要性を排除し、したがってこの依存関係を排除するために、何らかの方法でコードを再設計する必要があります。
D1.h
または、変更して変更しないことで解決できますD2.h
。ただし、そのパスをたどるには、「きめ細かい」友達宣言を置き換える必要があります
friend int D2::get(D1&);
より抜本的で寛容な
friend class D2;
D2.h
からの包含を削除しD1.h
ます。
以前のフレンド宣言では、クラスD2
が完全である必要があります。これは、実際には「壊れない」依存関係を作成するものです。後者の宣言は完全である必要はありませんD2
。