10

クラスがC++で作成される前に、クラスのオブジェクトを宣言する方法はありますか?2つのクラスを使用しようとしているので、最初のクラスには2番目のクラスのインスタンスが必要ですが、2番目のクラスにも最初のクラスのインスタンスが含まれています。無限ループに陥る可能性があると思われるかもしれませんが、実際には、最初のクラスの前に2番目のクラスのインスタンスを作成する必要があります。

4

5 に答える 5

42

あなたはこのようなことをすることはできません:

class A {
    B b;
};
class B {
    A a;
};

最も明白な問題は、BのサイズがAのサイズに依存するため、コンパイラがクラスAを作成するために必要なサイズを認識していないことです。

ただし、これを行うことはできます。

class B; // this is a "forward declaration"
class A {
    B *b;
};
class B {
    A a;
};

クラスBを前方宣言として宣言すると、クラス全体を定義しなくても、そのクラスへのポインター(および参照)を使用できます。

于 2008-09-22T06:08:41.930 に答える
5

未定義のクラスのインスタンスを宣言することはできませんが、次のクラスへのポインターを宣言することはできます。

class A;  // Declare that we have a class A without defining it yet.

class B
{
public:
    A *itemA;
};

class A
{
public:
    B *itemB;
};
于 2008-09-22T06:07:05.070 に答える
2

テンプレートを使用した洗練されたソリューションがあります。

template< int T > class BaseTemplate {};
typedef BaseTemplate< 0 > A;
typedef BaseTemplate< 1 > B;
// A
template<> class BaseTemplate< 0 >
{
public:
   BaseTemplate() {} // A constructor
   B getB();
}

// B
template<> class BaseTemplate< 1 >
{
public:
   BaseTemplate() {} // B constructor
   A getA();
}

inline B A::getB() { return A(); }
inline A B::getA() { return B(); }

このコードは機能します!それで、なぜそれが機能するのですか?その理由は、テンプレートのコンパイル方法に関係しています。テンプレートは、実際にどこかでテンプレートを使用するまで、関数シグネチャの作成を遅らせます。これは、クラスAとBの両方がすでに完全に宣言されるまで、getA()もgetB()もシグニチャを分析しないことを意味します。それがこの方法の魔法です。

于 2008-09-22T16:04:23.653 に答える
0

これはあなたが望むものに近いですか:最初のクラスには2番目のクラスが含まれていますが、2番目のクラス(最初に作成される)には最初のクラスへの参照がありますか?

于 2008-09-22T06:08:34.117 に答える
0

これは相互参照と呼ばれます。ここに例を参照してください。

于 2008-09-22T06:11:04.547 に答える