35

ネストされたクラスを前方宣言し、それを外部クラスの具体的な (ポインター/参照ではない) データ メンバーの型として使用することは可能ですか?

IE

class Outer;

class Outer::MaybeThisWay   // Error: Outer is undefined
{
};

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

 MaybeThatOtherWay y;   // Error: MaybeThatOtherWay is undefined
};
4

6 に答える 6

39

そのようなネストされたクラスを前方宣言することはできません。

何をしようとしているのかによっては、外側のレイヤーでクラスではなく名前空間を使用できる場合があります。そのようなクラスを問題なく前方宣言できます。

namespace Outer {
   struct Inner; 
};

Outer::Inner* sweets;  // Outer::Inner is incomplete so 
                       // I can only make a pointer to it

Outer が絶対にクラスである必要があり、それを名前空間に押し込むことができない場合は、Inner を前方宣言するコンテキストで Outer を完全な型にする必要があります。

class Outer
{
   class Inner;  // Inner forward-declared
};  // Outer is fully-defined now

Outer yes;  // Outer is complete, you can make instances of it
Outer::Inner* fun;  // Inner is incomplete, you can only make 
                    // pointers/references to it

class Outer::Inner 
{
};  // now Inner is fully-defined too

Outer::Inner win;  // Now I can make instances of Inner too
于 2010-04-08T14:25:13.257 に答える
15

含まれるクラスを完全に指定せずに、ネストされたクラスを前方宣言する方法はありません。この小さなトリックで問題は解決しますが、

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

私の命名規則Outer_Innerは有効なクラス名ではないため、これは私にとってはうまくいきます。したがって、ネストされたクラスを参照していることは明らかです。

次のように、ネストされたクラスを前方宣言することはまだできません。

class Outer::Inner;

しかし、少なくとも次のように前方宣言できます。

class Outer_Inner;

Outer_Inner の外観が気に入らない場合は、ネストされたクラスの命名規則を自分の好みに合わせて採用できます。 Outer__InnerOuter_nested_Innerなど

于 2010-04-08T14:50:02.390 に答える
1

クラスが前方宣言されている場合 (ただし、完全な定義がまだない場合)、コンパイラはクラスのサイズ (およびそのフィールドの名前) をまだ認識していないため、クラスへのポインターのみを宣言できます。または方法)。

于 2010-04-08T13:58:14.187 に答える
1

いいえ、しかし、何が問題なのですか

class Outer {
public:  //or protected or private
    class Inner {
    };

private:
    Inner foo;
};

私が何かを見落としていない限り、前方宣言はここでは意味がありません(あなたの質問には多くの詳細が欠けているので、これは可能です)

クラスが前方宣言されている場合、前方宣言された型のオブジェクトへの参照またはポインターのみを宣言できることに注意してください。メンバーや関数へのアクセスなど、それ以外のことはできません。

于 2010-04-08T13:56:07.683 に答える
0

関数パラメーターまたは静的変数として型が必要な場合は、クライアント側で行うことができます。たとえば、Outer からイベント通知を受け取るには:

インターフェース:

class Client {
public:
private:
    static void gotIt(int event);
    class Helper;
};

実装:

#include <outer.hpp>

class Client::Helper {
public:
    static void fromOuter(Outer::Inner const& inner) 
    { 
        gotIt(inner.event());
    }
};
于 2015-12-21T17:38:29.403 に答える
0

参照でもポインターでもないtype の属性を宣言する場合MaybeThatOtherWay、コンパイラーはクラスの完全な定義を認識して外部クラスのサイズを判別する必要があります。したがって、ネストされたクラスであるかどうかにかかわらず、前方宣言とその種のフィールド宣言を使用することはできません。

于 2010-04-08T14:05:40.683 に答える