Dichiarazioni di classi annidate
La classe può essere dichiarata all'interno dell'ambito di un'altra classe. Tale classe viene denominata "una classe annidata". Le classi annidate sono considerate all'interno dell'ambito della classe contenitore e possono essere utilizzate all'interno di tale ambito. Per fare riferimento a una classe annidata da un ambito diverso dal relativo ambito contenitore immediato, è necessario utilizzare un nome completo.
Nell'esempio seguente viene illustrato come dichiarare classi annidate:
// 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 e BufferedIO::BufferedOutput vengono dichiarate all'interno di BufferedIO. Questi nomi di classe non sono visibili al di fuori l'ambito della classe BufferedIO. Tuttavia, un oggetto di tipo BufferedIO non contiene alcun oggetto dei tipi BufferedInput o BufferedOutput.
Le classi annidate possono utilizzare direttamente nomi, nomi dei tipi, nomi dei membri statici ed enumeratori solo dalla classe contenitore. Per utilizzare i nomi degli altri membri della classe, è necessario utilizzare puntatori, riferimenti o nomi di oggetto.
Nell'esempio BufferedIO precedente, all'enumerazione IOError possono accedere direttamente le funzioni membro delle classi annidate, BufferedIO::BufferedInput o BufferedIO::BufferedOutput, come illustrato nella funzione good.
Nota
Le classi annidate dichiarano solo tipi all'interno dell'ambito della classe.Non comportano la creazione di oggetti contenuti della classe annidata.Nell'esempio precedente vengono dichiarate due classi annidate ma non viene dichiarato alcun oggetto di questi tipi di classe.
Un'eccezione alla visibilità nell'ambito di una dichiarazione di classe annidata è quando il nome di un tipo viene dichiarato con una dichiarazione con prototipo. In questo caso, il nome della classe dichiarata dalla dichiarazione con prototipo è visibile all'esterno della classe contenitore, con il relativo ambito definito come il più piccolo ambito contenitore di tipo non classe. Di seguito è riportato un esempio.
// 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;
}