Getter und Setter
-
SeppJ,
was ergibt es für einen Sinn solch eine Unterscheidung zu treffen?
Sagen wir mal, wir haben eine Implementierung I von Klasse X und eine Implementierung J von Klasse X. Beide Implementierungen könnten die Daten komplett anders vorhalten. Während Methode Y bei Implementierung I dann ein Getter wäre, wäre sie in Implementierung J kein Getter mehr. Das würde bedeuten, dass es Implementierungsabhängig ist, ob Methode Y von Klasse X ein Getter ist oder nicht.
-
SeppJ schrieb:
Die hier diskutierten Getter und Setter aber gerade nicht! Das ist doch gerade das was dot aussagen will. Getter und Setter die einfach nur private member quasi-public machen sind oft unnötig und oft Zeichen schlechten Designs. Memberfunktionen die tatsächlich Arbeit verrichten und dabei private Member ändern (eventuell auch nur einen) sind hingegen Musterbeispiele für objektorientiertes Design.
Grundsätzlich führt man Getter/Setter doch gerade deshalb ein, weil man die Freiheit haben will, später irgendwelche Implementierungsdetails zu ändern, ohne das der Clientcode angepasst werden muss. Das es schlecht ist, prinzipiell jeden privaten Member über Setter/Getter public zu machen, ist wohl klar. Dann kann man sich auch gleich das private sparen.
Mir erschließt sich jedoch nicht, wie Du aus der Frage des TO schließen willst, dass es um das prinzipielle publikmachen von Klasseninterna über Setter/Getter geht. Ich lese daraus eine Frage nach der Namenskonvention, und nicht mehr und nicht weniger.SeppJ schrieb:
Aber gerade push_back, reserve und resize sind Gegenbeipiele zu Settern.
Wieso insbesondere
reserve
undresize
Gegenbeispiele für Setter sind, erschließt sich mir auch nicht. Wenn Du Setter als bloßes Mittel zum setzen einer Variable auf einen Wert siehst, dann hast Du den Grund dafür irgendwie nicht verstanden. Aus Client-Sicht tue ich nämlich genau das: Ich setze etwas auf einen gewünschten Wert.
Es gibt da so ein tollen Beispiel für eine Klasse für komplexe Zahlen. Dort wird die Implementierung von Polarkoordinaten auf kartesische Koordinaten umgestellt, weil dem Autor aufgefallen ist, dass dies in seinem Kontext effizienter ist. Das Interface ändert sich dabei nicht. Auch nicht die Tatsache, dass esreal
undimag
sowie für Betrag und Winkel Setter und Getter gibt.
-
So, und ich denke, worauf ihr abzielt ist eine ganz andere Aussage. Ein öffentlicher Getter/Setter gibt dem Benuter eine Garantie, dass ein solcher Zustand in irgendeiner Form von Objekten dieser Klasse verwaltet wird. Wenn man also unnötige Getter/Setter anbietet, dann muss man umso mehr Arbeit reinstecken, wenn man die Implementierung später ändert, um die Garantien, die die Schnittstelle gibt weiterhin zu erfüllen.
-
Decimad schrieb:
So, und ich denke, worauf ihr abzielt ist eine ganz andere Aussage. Ein öffentlicher Getter/Setter gibt dem Benuter eine Garantie, dass ein solcher Zustand in irgendeiner Form von Objekten dieser Klasse verwaltet wird. Wenn man also unnötige Getter/Setter anbietet, dann muss man umso mehr Arbeit reinstecken, wenn man die Implementierung später ändert, um die Garantien, die die Schnittstelle gibt weiterhin zu erfüllen.
Versteh ich nicht. Wenn auf die Attribute zugegriffen werden muss, hat man den Aufwand doch so oder so und wenn man mit anderen Methoden irgendwas erreichen kann, wird man die doch (vermutlich) sowieso verwenden.
Ich würde mich jetzt aber auch nicht so auf die Begriffe Getter/Setter einschießen. Entspricht das irgend einem irgendwo definierten Terminus? Würde ich jetzt inuitiv verneinen.
-
Ich versuchte ja gerade in meiner Aussage davor darzulegen, dass eine Spezialisierung der Begriffe Getter/Setter über diejenige der Veränderung eines Astrakten Zustandes für den Benutzer gar keinen Sinn ergäbe, weil es von der Implementierung abhängt, ob die Begriffe dann zuträfen oder nicht.
-
Ich oute mich hiermit als Troll und danke euch dafür, dass ihr mitgespielt habt
-
Dann danke, dass du die Diskussion angeregt hast!
-
@Tachyon: Was wäre dann der Unterschied zwischen Gettern/Settern und jeder beliebigen anderen Memberfunktion? Alle Memberfunktionen dienen letztlich dazu den Status des Objekts zu verändern oder zu erfahren.
-
SeppJ schrieb:
@Tachyon: Was wäre dann der Unterschied zwischen Gettern/Settern und jeder beliebigen anderen Memberfunktion? Alle Memberfunktionen dienen letztlich dazu den Status des Objekts zu verändern oder zu erfahren.
Eben, Namen sind Schall und Rauch.
SeppJ schrieb:
Nein, habe ich nicht. Aber wie soll push_back ein setter sein? Da muss kopiert werden, Zeiger gesetzt werden, eventuelle Zähler erhöht werden, wenn's schlimm kommt sogar neu allokiert und alles kopiert werden. Das steht alles in den Anforderungen an vector. Es ist unmöglich das durch Änderung einer Variablen zu erreichen.
Ebenso reserve und resize.
operator[] muss mindestens ein bisschen Pointerarithmetik machen. at() zudem vergleiche durchführen.
Deine Argumentation mit dem push_back hört sich für mich so an, als ob du die Namen der Funktionen anhand der Implementierung wählst. Wenn ich meine Methodennamen danach auswählen würde, was die Methode alles am Ende des Tages abarbeiten muß, würden wir ganz schön miese Methodennamen haben.
Mich interessiert als Client-Code überhaupt nicht, ob push_back irgendwas allokieren muß. Ich setze (set) mein Objekt an das Ende des Containers, und gut ist. Mich interessiert auch nicht, wie Size zustande kommt. Ich will die Größe wissen (get). Hauptsache sie liefert erstmal die richtige Größe, und keine falsche.
Klar ist
vector::set_X(T&)
hässlicher weil weniger Aussagefähig alsvector::push_back(T&)
. Aber dann ist einfach nur der Name der Funktion in DEM Fall weniger verständlich, als push_back.
-
Artchi schrieb:
Deine Argumentation mit dem push_back hört sich für mich so an, als ob du die Namen der Funktionen anhand der Implementierung wählst.
Wo liest du denn das heraus? Ich nenne Funktionen nach dem was sie tun. push_back ist ebenfalls ein guter Name, weil hinterher der Vector am Ende ein Element mehr hat. Wie es das macht, ist mir egal. Aus der Dokumentation von push_back weiß ich aber, dass es kein einfacher Setter in der Form ist, wie ihn Anfänger oftmals für alle privaten Member schreiben (also
getX(){return X;}
) und genau um die häufige sinnlosigkeit dieser Art von Memberfunktion ging es in diesem Thread. Ob man das die Funktion nungetX()
oderkdngekngiruegt()
nennt ist ganz egal. Fakt ist, dass solche Arten von Funktionen sehr oft unnötig sind und die Objektabstraktion kaputtmachen. Wichtige Ausnahmen wurden genannt.
Dies hat überhaupt gar nichts mit Funktionen zu tun, die den Zustand eines Objektes auf eine mit der Abstraktion konsistenten Art und Weise ändern oder nach außen kommunizieren. Dies ist doch gerade der Zweck der ganzen Objektorientierung. Um das abgedroschene Autobeispiel rauszuholen: Auch wenn meine Autoklasse einen Member namens Motor hat, so ist eine Funktion setMotor doch keine gute Funktionalität dieser Klasse, weil ein reales Auto welches die Klasse beschreiben soll, nicht einfach seinen Motor ändern kann.
Eine Memberfunktion push_back ist daher eine sehr sinnvolle Funktion, denn die Abstraktion eines Vektors ist eine Liste an der man hinten was dranhängen und wegnehmen kann und bei der man die Elemente über eine Nummer eindeutig erreichen kann. Eine sehr schlechte Memberfunktion wäre ein Setter (im Sinne vonsetX(T newX){X=newX;}
) für irgendwelche Implementierungsdetails des Vektors, zum Beispiel für den Pointer auf das erste Element (falls es einen solchen gibt). Und gerade das ist es, worauf dot hinaus wollte und was sicherlich auch jeder einsieht, außer irgendwelche Besserwisser die dann einfach die Begriffe Getter und Setter (bewusst?) anders interpretieren, obwohl dies aus dem Zusammenhang offensichtlich sein sollte.