入れ子になったクラスの宣言
クラスが他のクラスのスコープ内で宣言できます。このようなクラスはと呼ばれます 「入れ子にされたクラスと」入れ子になったクラスは外側のクラスのスコープ内にあると見なされその範囲内で使用できるようになります。現在の範囲の範囲内の入れ子になったクラスを参照するには完全修飾名を使用する必要があります。
次の例は入れ子になったクラスの宣言方法を示しています :
// nested_class_declarations.cpp
class BufferedIO
{
public:
enum IOError { None, Access, General };
// Declare nested class BufferedInput.
class BufferedInput
{
public:
int read();
int good()
{
return _inputerror == None;
}
private:
IOError _inputerror;
};
// Declare nested class BufferedOutput.
class BufferedOutput
{
// Member list
};
};
int main()
{
}
BufferedIO::BufferedInput と BufferedIO::BufferedOutput は BufferedIO 内で宣言されます。これらのクラス名はクラス BufferedIO のスコープ外からは参照できません。ただしBufferedIO 型のオブジェクトを型 BufferedInput または BufferedOutput のオブジェクトは含まれません。
入れ子になったクラスを直接静的メンバー名型名および外側のクラスからのみ列挙子を使用できます。他のクラス メンバーの名前を使用するにはポインター参照またはオブジェクト名を使用する必要があります。
BufferedIO の前の例では列挙型 IOError は関数 good に示すように入れ子になったクラスまたは BufferedIO::BufferedInputBufferedIO::BufferedOutput のメンバー関数によって直接アクセスできます。
[!メモ]
入れ子になったクラスはクラス スコープ内の型で宣言します。これらに入れ子になったクラスに含まれるオブジェクトは作成されません。前の例では2 種類の入れ子になったクラスを宣言していますがこれらのクラス型のオブジェクトを宣言できません。
入れ子になったクラスの宣言の範囲のレンダリングの例外は型名が事前宣言とともに宣言されます。この場合事前宣言によって宣言されたクラス名は小さい囲むとクラスのスコープに定義された範囲は外側のクラスの外部に表示されます。次に例を示します。
// nested_class_declarations_2.cpp
class C
{
public:
typedef class U u_t; // class U visible outside class C scope
typedef class V {} v_t; // class V not visible outside class C
};
int main()
{
// okay, forward declaration used above so file scope is used
U* pu;
// error, type name only exists in class C scope
u_t* pu2; // C2065
// error, class defined above so class C scope
V* pv; // C2065
// okay, fully qualified name
C::V* pv2;
}