Verständnisfrage zu Klassen - Zugriffskontrolle von Objekteparametern



  • Hallo Zusammen

    Ich habe eine Verständnisfrage zu den Klassen.
    Wenn ich eine Klasse geschrieben habe, derren Eigenschaften im private Bereich liegen und über eine Methode ein Objekt derselben Klasse als Parameter erhalte kann ich über dieses Parameterobjekt direkt auf dessen Eigenschaften zugreifen.
    Dies funktioniert aber nur wenn das Objekt von der selben Klasse ist, in der auch die Methode steht.
    Ist das nicht eine Aufweichung der Datenkapselung und dürfte gar nicht funktionieren?

    class Person
    {
         std::string name;
    pulic:
         //konstruktoren etc.
         void zugriff(const Person &p)
         {
              if(name == p.name) // wieso funktioniert der Zugrif auf name von p?
                   std::cout << "Namen sind gleich" << std::endl;
         }
    };
    

    Vielen Dank schon für eure Erklärungen
    Gruss Inmeining



  • Doch das ist perfekt legal.
    Bei einer Klasse A die du in einer Methode der Klasse A instanzierst kannst du auf deren privaten Member zugreifen.



  • Hmmm, interessant, aber ich werde das in dieseme Falle wohl akzeptieren, erleichtert auch gewisse arbeiten 😃
    Vielen Dank für die rasche Antwort 🙂



  • Das Private gilt nur auf Klassen-Ebene und nicht auf Instanz-Ebene. Deshalb geht das.

    Aber ich würde dir trotzdem empfehlen, nach Möglichkeit nicht direkt auf Membervariablen zu zugreifen. Auch wenn es nicht grundsätzlich falsch ist, was du da machst.



  • Artchi schrieb:

    Aber ich würde dir trotzdem empfehlen, nach Möglichkeit nicht direkt auf Membervariablen zu zugreifen.

    Kannst du das auch begründen?



  • manni66 schrieb:

    Artchi schrieb:

    Aber ich würde dir trotzdem empfehlen, nach Möglichkeit nicht direkt auf Membervariablen zu zugreifen.

    Kannst du das auch begründen?

    Ich vermute hier geht es um die Getter/Setter-Agrumentation, die du wahscheinlich kennen dürftest (?). Sie ermöglichen ein flexibleres Interface, da man damit auch noch nachträglich an zentraler Stelle Logik und Transformation von Daten an das Setzen und Holen von Membern hängen kann. Vielleicht möchte man später, das der Personnename gewisse Constraints erfüllt, oder er soll z.B., bevor er in die Membervariable geschrieben wird, UTF-8-normalisiert werden... oder der Name steht später vielleicht gar nicht mehr im Member 'name', sondern wird direkt aus einer Datenbank oder einer anderen Datenstruktur geholt.

    Es ist nicht verkehrt, direkt auf Member zuzugreifen, aber je nachdem wie sich die Software entwickelt, macht man sich damit spätere Änderungen eventuell deutlich schwerer.

    Finn



  • Grundsätzlich arbeite ich nur mit getter / setter methoden.
    Da ich eher per Zufall auf dieses Verhalten gestossen bin, war ich verwirrt.
    Soweit ist jetzt aber alles klar, mir ging es besonders darum zu wissen, ob diese Regel auch in anderen Situationen gilt oder ob es nur innerhalb der gleichen Klasse möglich ist.
    Direkt auf die Privaten Member zuzugreifen entspricht nicht meinem Stil, auch wenn ich nun weiss dass es in einer bestimmten Konstellation möglich ist.
    Für mich ist es in erster Linie einfach gut zu wissen 🙂



  • Ich weiß nicht, ich halte das "alles muss getter und setter haben" für irgendwie idiotisch.

    Gerade weil nach außen hin das Interface möglichst gleich bleiben soll!

    Angenommen, ich ändere meine interne Darstellung der Daten und baue die getter/setter dann so um, dass nach außen alles so wie früher bleibt.

    Wenn ich dann z.B. einen operator== habe, dann kann es doch deutlich effizienter sein, jeweils die internen Darstellungen der Objekte zu vergleichen statt über die kovertierenden getter zu gehen. Gut, jetzt kannst du einwenden, dass ich dann auch für die interne Darstellung private getter machen könnte. Aber wozu - nur um == zu implementieren?

    Ich bestreite nicht, dass getter/setter oft sehr sinnvoll sind, aber ich sehe irgendwie nicht, dass man sie aus Prinzip für alle Zugriffe nutzen sollte.



  • Finnegan schrieb:

    Ich vermute hier geht es um die Getter/Setter-Agrumentation, die du wahscheinlich kennen dürftest (?). Sie ermöglichen ein flexibleres Interface,

    Ja, eben. Es geht dabei um die Schnittstelle nach außen. In der Implementierung der Klasse sind die internen Details bekannt und können verwendet werden. Das ist genau der Punkt, warum public/private genauso funktioniert, wie es der OP festgestellt hat.



  • getter/setter sind allerdings auch oft sehr unnötig, nämlich dann, wenn es entweder eine bessere möglichkeit zur abstraktion gibt oder dann, wenn gar keine abstraktion nötig ist, z.b.

    struct point { int x; int y; };
    


  • Ach was, gerade beim Punkt geht das doch anders, da muss man doch die Darstellung nach außen hin unbedingt vom Koordinatensystem abstrahieren:

    struct point { double x() const = 0; double y() const = 0; };
    struct pointKartesich : public point { double x_, y_; double x() const { return x;} double y() const { return y; } };
    struct pointPolar : public point { double r_, phi_; double x() const { return r_*cos(phi_); } double y() const { return r_*sin(phi_); } };
    

    (Nur falls jemand auf die Idee kommt, ich würde das ernst meinen: Nein, so würde ich es NICHT machen!!!!)



  • manni66 schrieb:

    Finnegan schrieb:

    Ich vermute hier geht es um die Getter/Setter-Agrumentation, die du wahscheinlich kennen dürftest (?). Sie ermöglichen ein flexibleres Interface,

    Ja, eben. Es geht dabei um die Schnittstelle nach außen. In der Implementierung der Klasse sind die internen Details bekannt und können verwendet werden. Das ist genau der Punkt, warum public/private genauso funktioniert, wie es der OP festgestellt hat.

    Ja, da gebe ich dir recht. Für solche internen Sachen kann man sich das sparen. Muss zugeben, dass ich das nur oberflächlich gelesen hab (Asche, Haupt und so), sorry! 😉

    Finnegan


Log in to reply