Zugriff auf privates Attribut außerhalb der Klasse!?
-
Kann mir hier bitte jemand erklären, warum folgender Code compiliert?
Meines Wissens nach sollte das unmöglich sein:#include <iostream> using namespace std; class Test{ public: Test(int x){ this->value = x; } bool operator<(Test & other){ return this->value < other.value;//private??? } private: int value; }; int main(){ Test a(1); Test b(2); cout << endl << (a < b) << endl; }In Zeile 10 wird auf das Attribut value zugegriffen, das eigentlich als private deklariert ist.
Warum ist das möglich?
Ist da vielleicht an Operator-Methoden irgendetwas besonderes, wovon ich nichts weiß?
-
Du greifst innerhalb der Klasse Test auf ein Element der Klasse Test zu. Vollkommen legal. Außerhalb der Klasse kannst du nicht mehr auf private Elemente der Klasse zugreifen.
-
Innerhalb der Klasse hat man schon immer auf private Member zugreifen dürfen.
operator<ist eine Memberfunktion der Klasse (wäre übrigens besser global, warum siehst du hier) undvalueeine Membervariable.
-
Das private ist auf Klassenebene und nicht auf Instanzebene.
-
Alles klar.
Aus irgendeinem Grund dachte ich, dass es nicht geht, weil "other" hier eine andere Instanz ist als this. Aber anscheinend reicht es, dass die Klasse die selbe ist.
Seltsam, dass mir das erst jetzt auffällt.Danke.
-
Vielleicht noch als Hinweis: Bei
protectedsieht es anders aus. Innerhalb einer Klasse darf man nicht aufprotected-Member zugreifen, die zwar in einer Basisklasse deklariert wurden, aber deren Objekt nicht das eigene Basisobjekt ist.
-
Nexus schrieb:
Vielleicht noch als Hinweis: Bei
protectedsieht es anders aus. Innerhalb einer Klasse darf man nicht aufprotected-Member zugreifen, die zwar in einer Basisklasse deklariert wurden, aber deren Objekt nicht das eigene Basisobjekt ist.Hi,
wie meinst Du das genau?
das hier funktioniert jedefalls und Codepad, xlC und gcc#include <iostream> using namespace std; class A { public: A(int i) : a(i) {} protected: int a; }; struct B : public A { B(int i) : A(i) {} void check(B const& b) { cout << "eigener: " << a << "\n"; cout << "fremder: " << b.a << "\n"; } }; int main() { B b1(1), b2(2); b1.check(b2); return 0; }Ich vermute deshalb, Du meinst etwas Anderes (wusste das auch schonmal, bekomms aber gerade nicht auf die Kette).
Gruß,
Simon2.
-
Hallo,
Es egal, ob man Elemente als protected oder private deklariert, solange es keine abgeleiteten Klassen gibt. Von außerhalb der Klasse kann man weder auf private- , noch auf protected-Elemente zugreifen. Allerdings kann man in einer angeleiteten Klasse nicht auf private-Elemente der Basisklasse zugreifen, wohl aber auf Elemente, die in der Basisklasse als protected deklariert wurden.
MfG, Jochen
-
Hi Simon2,
Diese Regel betrifft Zugriff auf
protected-Member bei Basisobjekten. Mitvoid check(A const& b) { // <- hier A statt B cout << "eigener: " << a << "\n"; cout << "fremder: " << b.a << "\n"; }wird es nicht kompilieren.
C++ Standard, §11.5/1 schrieb:
When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class).
Hier gabs auch mal einen Thread dazu.
-
Nexus schrieb:
Hi Simon2,
Diese Regel betrifft Zugriff auf
protected-Member bei Basisobjekten. ...Unter dieser Formulierung hätte ich spontan auch mein Codebeispiel verstanden. Auch da wird auf ein Basisobjekt zugegriffen und auch dort ist das zugegriffene Member sowohl protected als auch Member der Basisklasse.
Nexus schrieb:
Mit
void check(A const& b) { // <- hier A statt B cout << "eigener: " << a << "\n"; cout << "fremder: " << b.a << "\n"; }wird es nicht kompilieren.
...Stimmt - aber mit private auch nicht.

Aber ich habe schon verstanden: Mit protected hätte man erwartet, dass es funktioniert, weil B ja abgeleitet ist.
Und in meinem Beispiel "funktioniert" der Zugriff, weil sichergestellt ist, dass er "über die Klasse B läuft"...Danke - jetzt habe ich es wieder!
Gruß,
Simon2.