Verschachtelte Klassen
Eine Deklaration einer Klasse/Struktur oder Union kann innerhalb einer anderen Klasse erscheinen. Eine solche Deklaration deklariert eine verschachtelte Klasse.
[bearbeiten] Erklärung
Der Name der verschachtelten Klasse existiert im Geltungsbereich der umschließenden Klasse, und die Namensauflösung von einer Memberfunktion einer verschachtelten Klasse besucht den Geltungsbereich der umschließenden Klasse, nachdem der Geltungsbereich der verschachtelten Klasse untersucht wurde. Wie jeder Member seiner umschließenden Klasse hat die verschachtelte Klasse Zugriff auf alle Namen (private, protected usw.), auf die die umschließende Klasse Zugriff hat, ist aber ansonsten unabhängig und hat keinen besonderen Zugriff auf den this-Zeiger der umschließenden Klasse. Deklarationen in einer verschachtelten Klasse können beliebige Member der umschließenden Klasse verwenden, gemäß den üblichen Nutzungsregeln für die nicht-statischen Member.
int x, y; // globals class enclose // enclosing class { // note: private members int x; static int s; public: struct inner // nested class { void f(int i) { x = i; // Error: can't write to non-static enclose::x without instance int a = sizeof x; // Error until C++11, // OK in C++11: operand of sizeof is unevaluated, // this use of the non-static enclose::x is allowed. s = i; // OK: can assign to the static enclose::s ::x = i; // OK: can assign to global x y = i; // OK: can assign to global y } void g(enclose* p, int i) { p->x = i; // OK: assign to enclose::x } }; };
Friend-Funktionen, die innerhalb einer verschachtelten Klasse definiert sind, haben keinen besonderen Zugriff auf die Member der umschließenden Klasse, auch wenn die Auflösung aus dem Körper einer Memberfunktion, die innerhalb einer verschachtelten Klasse definiert ist, die privaten Member der umschließenden Klasse finden kann.
Definitionen von Membern einer verschachtelten Klasse außerhalb der Klasse erscheinen im Namespace der umschließenden Klasse
struct enclose { struct inner { static int x; void f(int i); }; }; int enclose::inner::x = 1; // definition void enclose::inner::f(int i) {} // definition
Verschachtelte Klassen können vorwärts deklariert und später definiert werden, entweder innerhalb desselben umschließenden Klassenkörpers oder außerhalb davon
class enclose { class nested1; // forward declaration class nested2; // forward declaration class nested1 {}; // definition of nested class }; class enclose::nested2 {}; // definition of nested class
Deklarationen von verschachtelten Klassen unterliegen Mitgliedszugriffsregeln. Eine private Mitgliedsklasse kann außerhalb des Geltungsbereichs der umschließenden Klasse nicht benannt werden, obwohl Objekte dieser Klasse manipuliert werden können.
class enclose { struct nested // private member { void g() {} }; public: static nested f() { return nested{}; } }; int main() { //enclose::nested n1 = enclose::f(); // error: 'nested' is private enclose::f().g(); // OK: does not name 'nested' auto n2 = enclose::f(); // OK: does not name 'nested' n2.g(); }
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 45 | C++98 | die Member einer verschachtelten Klasse können nicht auf die umschließende Klasse und ihre Friends zugreifen |
sie haben die gleichen Zugriffsrechte wie andere Member der umschließenden Klasse (löst auch CWG-Probleme #8 und #10) |
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 11.4.12 Deklarationen verschachtelter Klassen [class.nest]
- C++20 Standard (ISO/IEC 14882:2020)
- 11.4.10 Deklarationen verschachtelter Klassen [class.nest]
- C++17 Standard (ISO/IEC 14882:2017)
- 12.2.5 Deklarationen verschachtelter Klassen [class.nest]
- C++14 Standard (ISO/IEC 14882:2014)
- 9.7 Deklarationen verschachtelter Klassen [class.nest]
- C++11 Standard (ISO/IEC 14882:2011)
- 9.7 Deklarationen verschachtelter Klassen [class.nest]
- C++98 Standard (ISO/IEC 14882:1998)
- 9.7 Deklarationen verschachtelter Klassen [class.nest]