Déclarations de classes imbriquées
Une classe peut être déclarée dans la portée d'une autre classe. Il s'agit d'une « classe imbriquée ». Les classes imbriquées sont prises dans la portée de la classe englobante et peuvent être utilisées dans cette portée. Pour faire référence à une classe imbriquée à partir d'une portée différente de sa portée englobante immédiate, vous devez utiliser un nom qualifié complet.
L'exemple suivant montre comment déclarer des classes imbriquées :
// 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 et BufferedIO::BufferedOutput sont déclarées dans BufferedIO. Ces noms de classe ne sont pas visibles en dehors de la portée de la classe BufferedIO. Toutefois, un objet de type BufferedIO ne contient aucun objet de type BufferedInput ou BufferedOutput.
Les classes imbriquées ne peuvent utiliser directement les noms, les noms de types, les noms des membres statiques et les énumérateurs qu'à partir de la classe englobante. Pour utiliser des noms d'autres membres de classe, vous devez utiliser des pointeurs, les références ou des noms d'objet.
Dans l'exemple BufferedIO précédent, l'énumération IOError est accessible directement par les fonctions membres des classes imbriquées, BufferedIO::BufferedInput ou BufferedIO::BufferedOutput, comme indiqué dans la fonction good.
Notes
Les classes imbriquées déclarent uniquement des types dans la portée de classe.Elles n'entraînent pas la création d'objets contenus de la classe imbriquée.L'exemple précédent déclare deux classes imbriquées mais ne déclare aucun objet de ces types de classe.
Il existe une exception à la visibilité de portée d'une déclaration de classe imbriquée : lorsqu'un nom de type est déclaré avec une déclaration anticipée. Dans ce cas, le nom de classe déclaré par la déclaration anticipée est visible en dehors de la classe englobante, sa portée étant définie de telle sorte qu'elle est la plus petite portée englobante sans classe. Par exemple :
// 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;
}