Wenn ich eine innere Klasse in C ++ definiere, ist sie automatisch ein Freund der Klasse, die sie enthält? Ist das zum Beispiel legal:
class Outer {
public:
class Inner {
public:
void mutateOuter(Outer& o);
};
private:
int value;
};
void Outer::Inner::mutateOuter(Outer& o) {
o.value ++; // Legal? Or not?
}
Ich frage, weil auf einigen Compilern, die ich ausprobiert habe (VS2003), dieser Code nicht funktioniert, aber ich habe zumindest anekdotisch gehört, dass er auf einigen Compilern funktioniert. Ich kann keinen relevanten Abschnitt in der C ++ - Spezifikation dazu finden, und wenn jemand etwas Bestimmtes zitieren kann, das besagt, dass es legal ist oder nicht, wäre das großartig.
c++
friend
nested-class
templatetypedef
quelle
quelle
&&
Operator abrufen können). Es tut mir leid, wenn ich in diesem Fall ein Stickler bin, aber ich unterrichte einen C ++ - Programmierkurs und möchte mir der Antwort sehr sicher sein, bevor ich meinen Schülern etwas erzähle.Antworten:
Nachdem ich hier selbst mehr oder weniger dieselbe Frage gestellt hatte , wollte ich die (anscheinend) aktualisierte Antwort für C ++ 11 teilen:
Zitiert von https://stackoverflow.com/a/14759027/1984137 :
class E { int x; class B { }; class I { B b; // OK: E::I can access E::B int y; void f(E* p, int i) { p->x = i; // OK: E::I can access E::x } }; }
quelle
Bis C ++ 11 (dh C ++ 98 und C ++ 03)
In C ++ 98 und C ++ 03, verschachtelte Klasse kann nicht Zugriff
private
undprotected
Mitglieder von Standardklasse umschließt.Der C ++ Standard (2003) sagt in $ 11.8 / 1 [class.access.nest],
Beispiel aus dem Standard selbst:
class E { int x; class B { }; class I { B b; // error: E::B is private int y; void f(E* p, int i) { p->x = i; // error: E::x is private } }; int g(I* p) { return p->y; // error: I::y is private } };
Seit C ++ 11
Die obige Einschränkung wurde seit C ++ 11 entfernt. Nun sind die verschachtelten Klassen können Zugriff auf die
private
und dieprotected
Mitglieder der umschließenden Klasse:class E { int x; class B { }; class I { B b; // ok: even though E::B is private int y; void f(E* p, int i) { p->x = i; // ok: even though E::x is private } }; int g(I* p) { return p->y; // ok: even though I::y is private } };
Hoffentlich hilft das.
quelle
g()
wird der Code ab C ++ 11 problemlos kompiliert . Sollte die Antwort aktualisieren.Da der Fragesteller eine der Antworten akzeptiert zu haben scheint, ist dies nur eine Ergänzung.
Der Standard scheint die Spezifikation bezüglich der Zugänglichkeit geändert zu haben.
§11.8 / 1 in C ++ 98 besagt:
§ 11.8 / 1 in N1804 (nach TR1) besagt:
Ich denke, aktuelle C ++ - Compiler befolgen neuere Spezifikationen.
quelle
class Enclosing {private: enum PrivateEnum {VALUE}; class Nested {/*accessing enclosing class' member type*/ PrivateEnum e;}; };
.class A { int i; class B { struct C { void f( A* x ) { x->i = 0; } }; }; };
der Standard zulässig ist, ist es vermutlich die Absicht des Standards, dies zuzulassen. VC8, g ++ 3.4.5 und Comeau Online erlauben es. Aber ich kann nichts Bestimmtes sagen. Wenn Sie besorgt sind, würde ich empfehlen, diese Frage in StackOverflow zu posten. Jemand mit detaillierteren Kenntnissen als ich wird antworten.class A {int i; class B {A *a; int f() {return a->i;} }; };
der Klasse B ist ein Mitglied der Klasse A, aber B :: f () ist ein Mitglied der Klasse A :: B, nicht A! Aber ich habe gerade ein anderes Zitat aus DR 45 gefunden, das dies klarstellen könnte: "Ein Mitglied einer Klasse kann auch auf alle Namen als die Klasse zugreifen, zu der es gehört." Mit anderen Worten, B :: f () "erbt" das Zugriffsrecht der Klasse B.Diese Antwort bezieht sich auf die (veraltete) C ++ 03-Spezifikation. Die akzeptierte Antwort auf diese Frage ist aktueller.
Nun, ich finde es albern, diese Frage jetzt zu stellen, weil ich gerade den relevanten Teil der Spezifikation gefunden habe, der dies abdeckt: §11.8 / 1:
(Meine Betonung)
Es sieht also so aus, als ob innere Klassen keine speziellen Zugriffsrechte haben.
quelle
Ich weiß nicht genau, wo ich mich befinde, aber ich erinnere mich, dass ich die Spezifikationen durchgelesen und festgestellt habe, dass alle privaten Daten in einer Klasse vor allen anderen Klassen, einschließlich verschachtelter Klassen, verborgen sind.
Grundsätzlich definiert das Verschachteln einer Klasse einen bestimmten Bereich und nicht den Zugriff auf Berechtigungen.
quelle