C ++入れ子のクラス/前方宣言の問題
-
25-09-2019 - |
質問
は、それが可能とするために、次に、入れ子になったクラスを転送し、宣言コンクリート(ないポインタへ/参照)で外部クラスのデータメンバ
のための型としてそれを使用することですすなわちます。
class Outer;
class Outer::MaybeThisWay // Error: Outer is undefined
{
};
class Outer
{
MaybeThisWay x;
class MaybeThatOtherWay;
MaybeThatOtherWay y; // Error: MaybeThatOtherWay is undefined
};
解決
あなたはそのような入れ子になったクラスを、前方宣言することはできません。
あなたがやろうとしている内容に応じて、多分あなたは、外側の層の名前空間ではなく、クラスを使用することができます。あなたは転送しない、宣言することができ、このようなクラスを何の問題ます:
namespace Outer {
struct Inner;
};
Outer::Inner* sweets; // Outer::Inner is incomplete so
// I can only make a pointer to it
あなたの外側は絶対クラスでなければなりません、そしてあなたが名前空間にそれを靴ホーンができない場合は、、そして、あなたが前方にインナーを宣言コンテキスト内の完全な型であることを外のために必要があります。
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
他のヒント
は、前方に完全に含まれているクラスを指定せずに、ネストされたクラスを宣言する方法はありません。この小さなトリックはちょっとかかわらず、問題を修正する
class Outer_Inner
{
};
class Outer
{
public:
typedef Outer_Inner Inner;
};
それは、ネストされたクラスを参照していることは明らかですので、私の命名規則Outer_Inner
のように、私にとってこの作品は、有効なクラス名ではありません。
あなたはまだ前方に、このような入れ子になったクラスを宣言することはできません。
class Outer::Inner;
しかし、少なくともそれは前方で宣言することができます:
class Outer_Inner;
あなたはOuter_Innerは、あなたがより良いスーツあなたの好みという入れ子になったクラスの命名規則を採用する可能性が見え方が気に入らない場合。 Outer__Inner
、Outer_nested_Inner
、など。
はありませんが、何を間違ったのです。
class Outer {
public: //or protected or private
class Inner {
};
private:
Inner foo;
};
私は(あなたの質問は、多くの詳細に欠けているよう可能見ている)何かが欠けていない限り、を宣言フォワードは、ここでは意味がありません。 クラスが前方に、あなたは前方にのみ宣言された型のオブジェクトへの参照またはポインタを宣言することができ宣言されている場合、
は、覚えておいてください。あなたはそれのメンバーや機能へのアクセスを含め、それで何かを行うことはできません。
クラスは、前方宣言された(しかし、あなたはまだ完全な定義を持っていない)場合、コンパイラは、まだクラスの大きさ(や名前を知らないので、あなただけ、それへのポインタを宣言することができますそのフィールドやメソッド)のます。
MaybeThatOtherWay
の属性ではなく、参照やポインタを宣言する場合は、、コンパイラが外部クラスのサイズを決定するために、クラスの完全な定義を知っている必要があります。したがって、あなたはそれが入れ子になったクラスだかどうか、前方宣言とフィールドの宣言のようなものを使用することはできません。
は、それがクライアント側で行うことができます。例えば、外側からのイベント通知を受信するには:
インターフェース:
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());
}
};