0

コードは次のようになります。

class B {/*something*/};

class D1: public B {
public:
void set() = 0;
friend int D2::get(D1&);
private: 
int a;
}
class D2: public B {
public:
int get(D1& d) {return d.a;}
}

"B.h"派生クラスの.hファイル("D1.h" and "D2.h")とD2.hD1の「」の両方にD2を含めまし"D1.h"たが、コンパイルエラーが発生し続けます。

...\D2.h ... use of undefined type D1

だから私は何を間違っているのですか?ありがとう。

4

3 に答える 3

3

円形の包含を作成しましたD1.hD2.hに含め、またに含めD2.hましたD1.h。循環包含は機能せず、何も達成しません。

循環包含は、クラス定義間の循環依存の直接的な結果です。コードでは、両方のクラス定義が、両方のクラスタイプが完全である(完全に定義されている)必要がある方法で相互に参照しています。つまり、何をしても、コードをそのままコンパイルすることはできません。クラス定義間の循環依存を解消する必要があります。

あなたの場合、それは次の方法で行うことができます。

変更しないでください。つまり、クラスの定義をD1.hそのまま含めD2.hて保持します。D1.hD1

ただし、に含めないでください。代わりに、の前方宣言を導入してください。D1.hD2.hD1D2.h

class D1;

の定義をD2に変更します

class D2: public B {
public:
  int get(D1& d);
};

get注:クラスの定義でメソッドを正しく定義しようとしないでくださいD2。の定義を他の場所に再配置する必要があります。ここでは、の完全な定義も表示されます(たとえば、との両方を含める必要があります)。D2::getD1D2.cppD1.hD2.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

于 2012-08-16T16:11:10.753 に答える
0

D1の定義がD2に依存し、D2の定義がD1に依存する場合は、両方のクラスを転送参照する必要があります。

class B;
class D1;
class D2;
于 2012-08-16T16:06:31.397 に答える
0

その時点で、コードがD2何であるかを言うことは何もありD2ませんでした(コンパイラはそれを理解することを先取りしていません)。したがって、の定義を開始する前にD2追加して、コンパイラに何を伝える必要があります。class D2;D1

于 2012-08-16T16:07:48.530 に答える