PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zugriffsrechte bei Klassenvariablen


Gnafoo
2004-03-28, 12:57:51
So ich habe mal einige Fragen bezüglich der Zugriffsrechte beim Objektorientierten Programmieren (C++).

Also prinzipiell braucht man Zugriffsrechte ja, um anderen Klassen daran zu hindern bestimmte Variablen zu ändern und Funktionen aufzurufen, die die Klasse nur intern benutzen sollte. Sei es, um zu verhindern, dass eine andere Klasse die Daten verändert und das Funktionieren der eigentlichen Klasse verhindert, oder um zu verhindern, dass bestimmte Funktionen ohne den Kontext aufgerufen werden und ungewollte Probleme auftreten.

Insofern ist es ja auch ein Schutz, damit man nicht selber etwas programmiert, das zu Problemen führen kann.

Auch irgendwelche getValue Funktionen, die eine Kopie der eigentlichen Variable zurückgeben, damit man zwar den Wert dieser auslesen, ihn aber nicht verändern kann machen Sinn.
Aber wenn man get- und set-Funktionen zusammen verwendet ist das doch eigentlich nur noch sinnvoll, wenn man dabei irgendeinen Code ausführen muss, der beim setzen dieser Variable irgendwelche Tasks ausführen muss oder andere Variablen updaten muss etc.

Bloß irgendwie hab ich das Gefühl, dass public Variablen möglichst überall vermieden werden. Ich meine, wenn man irgendwo eine get- und set-Funktion in einer Klasse hat, die beide lediglich den Wert einer Variable ändern, warum sollte man diese nicht ganz einfach public machen und sich die Funktionen sparen?

Mal gespannt, was ihr dazu sagt :)
cya DerTod

Abe Ghiran
2004-03-28, 13:13:29
Moin, moin..

Original geschrieben von Der Tod
Bloß irgendwie hab ich das Gefühl, dass public Variablen möglichst überall vermieden werden. Ich meine, wenn man irgendwo eine get- und set-Funktion in einer Klasse hat, die beide lediglich den Wert einer Variable ändern, warum sollte man diese nicht ganz einfach public machen und sich die Funktionen sparen?


Der Knackpunkt ist halt, daß man in den allermeisten Fällen komplexere Objekte hat bei denen eine setIrgendwas nicht nur eine Variable verändert, sondern auch noch andere Dinge tut.
Ein simples Beispiel wäre z.B eine Vektor Klasse, die aus Performance Gründen neben den Koordinaten auch noch die aktuelle Länge des Vektors als Variable speichert. Da müsste dann beim setzen einer der Koordinaten auch die Länge neu berechnet werden, z.B. so:

setX(double x){
this->x = x;

recalculateLength();
}

Wäre x public, könnte man die Variable einfach verändern ohne die Länge neu zu berechnen -> der Zustand des Vektors würde inkonsistent werden.

Aber selbst wenn man triviale Objekte hat, sollte man meiner Meinung nach immer getter / setter benutzen. Denn irgendwann wird das Objekt vielleicht doch mal komplexer, dann bleibt aber diese Komplexität hinter dem Interface (get / set Methoden) versteckt.
Würde man die Vektor Klasse z.B. erst später um das speichern der Länge erweitern, macht das für den Aufrufer keinen Unterschied: Er ruft immer setX auf, um die X Koordinate zu setzen, daß auf einmal dabei auch die Länge neuberechnet wird, merkt er gar nicht.

Und darum geht es ja beim oo Design: Das interne Verhalten eines Objektes wird hinter einem Interface aus genau definierten Methoden versteckt, so daß für den Benutzer / Aufrufer eines Objektes die interne Implementierung keine Rolle mehr spielt.

Grüße, Jan

Gnafoo
2004-03-28, 13:51:11
Ok aber z.b. in meinem Fall stellt die Klasse eigentlich nichts weiteres dar, als eine um ein paar Funktionen erweiterte struct, die einige Informationen speichert. (Triangles und Vertices und ein paar Zusammenhänge wie benachbarte Vertices etc.)

Ich denke nicht, dass ich später noch für die Variablen zusätzlichen Code bei der Zuweisung benötigen werde. Da wäre es dann schon etwas umständlich für jede Variable eine set- und get-Funktion zu schreiben.

Außerdem wäre der Aufwand zur Laufzeit größer, weil die Parameter erst einmal auf den Stack geladen werden müssen etc. Wenn man die Funktion inline macht könnte es sein, dass der Compiler wieder auf das gleiche kommt, aber nicht unbedingt.

Abe Ghiran
2004-03-28, 14:35:15
Ok, bei solchen low level Sachen gebe ich dir völlig Recht. Da benutze ich auch structs o.ä. für und es ist ja auch wirklich abzusehen, daß sich dort nicht mehr wirklich etwas ändert.

Ich sehe sowas aber eigentlich auch gar nicht als "richtiges" Objekt. Das sind ja nur sehr simple Datenklassen in die man was reinstopft und dann an die Api übergibt (bei mir vertex arrays). Großartige Interaktion mit anderen Objekten (bei der Irgendetwas schief gehen könnte) findet da ja gar nicht statt.

Aus eigener Erfahrung würde ich mir aber über solche Sachen wie "Parameter einer Funktion müssen ja auf den Stack, hmm daß kostet ja Zeit" erst mal keine Gedanken machen. Lieber erst mal sicher & sauber implementieren. Wenn es dann später mit der Geschwindigkeit hackt, kann man immer noch mit einem Profiler nach der genauen Ursache suchen und gezielt optimieren.

Gnafoo
2004-03-28, 14:53:55
Oke .. das klingt plausibel.
Einfach als struct ist eigentlich eine gute Lösung, die auch gut ins Konzept passt.

Danke für die Hilfe :)
cu DerTod

Trap
2004-03-28, 15:05:58
Zum Thema wann Klasse und wann einfach ein struct hat Bjarne Stroustrup eine eindeutige Regel:
http://www.artima.com/intv/goldilocks3.html

Mikrooptimierung wie Überlegungen über Stack und so ist das allerletzte was man bei der Programmentwicklung machen sollte. Stackoperationen sind sehr schnell und Compiler sind bei bei Mikrooptimierungen auch schon für sich ganz gut.