Getter und Setter



  • Artchi schrieb:

    dot schrieb:

    Ist push_back deiner Meinung nach ein Setter für die Größe eines std::vector?

    Ja, weil ich durch den push_back-Parameter, das übergebene Objekt in den Container setze (direkte Änderung). Die Size ist eine indirekte Änderung.

    Wenn du getter/setter so definierst, kann man selbstverständlich nichts ohne sie programmieren.

    Versteht man darunter aber eher so was

    Wikipedia schrieb:

    Eine Zugriffsfunktion, auch Zugriffsmethode oder Akzessor, ist in der objektorientierten Programmierung eine spezielle Methode, die eine einzelne Eigenschaft eines Objekts abfragt oder ändert.

    würde ich durchaus dazu raten, sie sparsam einzusetzen.



  • Artchi schrieb:

    Ja, weil ich durch den push_back-Parameter, das übergebene Objekt in den Container setze (direkte Änderung). Die Size ist eine indirekte Änderung.

    Dieser Argumentation nach müsste aber alles ein Setter oder Getter sein. Denn alles liefert Informationen über den Status oder hat Seiteneffekte. Und damit ist es auch nicht mehr schwierig zu begründen, dass man Setter und Getter immer braucht, sobald man Funktionalität benötigt.

    Artchi schrieb:

    Beispiel gefällig?

    Manchmal sind aber rohe ungekapselte Strukturen besser (weil einfacher und weil keine relevanten Nachteile). Gerade Vektorklassen halte ich für so ein Beispiel.



  • dot schrieb:

    [...]
    Ist push_back deiner Meinung nach ein Setter für die Größe eines std::vector?[...]

    Wenn die Standardbibliothek als Beispiel gegen Setter/Getter herhalten soll, dann geht das ziemlich nach hinten los. Neben den indirekten Settern wie push_back gibt es auch jede Menge direkte Setter und passende Getter dazu.
    Beim std::vector z.B.:
    `reserve() <-> capacity()

    resize() <-> size()

    operator[] <-> operator[]

    at() <-> at()

    push_back() <-> back()

    ` etc...



  • Nexus schrieb:

    Manchmal sind aber rohe ungekapselte Strukturen besser (weil einfacher und weil keine relevanten Nachteile). Gerade Vektorklassen halte ich für so ein Beispiel.

    Ja, Containerklassen sind schon eine Sonderstellung. Was wieder belegt, das man nicht generell sagen kann "Wenn ich DAS sehe, ist das schlecht!".
    Das mit den "offenen" Containerklassen steht übrigens auch (wenn ich mich nicht komplett täusche) auch im Scott Meyers drin. Weil man die Objekte nun mal wieder als Reference zurück geben muß. Aber z.B. die Size von einem Vector kann ich nicht direkt ändern.



  • Nexus schrieb:

    Artchi schrieb:

    Beispiel gefällig?

    Manchmal sind aber rohe ungekapselte Strukturen besser (weil einfacher und weil keine relevanten Nachteile). Gerade Vektorklassen halte ich für so ein Beispiel.

    Insbesondere POD-Strukturen sind mir in manchen Fällen lieber als eine Klasse, die die gleiche Funktionalität erfüllt. Der Grund ist vermutlich offensichtlich 😉


  • Mod

    Tachyon schrieb:

    dot schrieb:

    [...]
    Ist push_back deiner Meinung nach ein Setter für die Größe eines std::vector?[...]

    Wenn die Standardbibliothek als Beispiel gegen Setter/Getter herhalten soll, dann geht das ziemlich nach hinten los. Neben den indirekten Settern wie push_back gibt es auch jede Menge direkte Setter und passende Getter dazu.
    Beim std::vector z.B.:
    `reserve() <-> capacity()

    resize() <-> size()

    operator[] <-> operator[]

    at() <-> at()

    push_back() <-> back()

    ` etc...

    Alle von dir genannten Funktionen (außer evtl. size und capacity) machen sehr viel mehr als einfach nur Getter/Setter für Interna des vectors zu sein.



  • SeppJ schrieb:

    Alle von dir genannten Funktionen machen sehr viel mehr als einfach nur Getter/Setter für Interna der Klasse zu sein.

    Der Sinn von Gettern ist doch nicht die bloße Rückgabe eines Wertes, sondern gerade dass man das Abfragen/Setzen eines Wertes mit einer Aktion oder Konvertierung verbinden kann und das diese Dinge vor dem Client verborgen bleiben.



  • SeppJ schrieb:

    Alle von dir genannten Funktionen (außer evtl. size und capacity) machen sehr viel mehr als einfach nur Getter/Setter für Interna des vectors zu sein.

    Und woher weißt du das? Doch nur weil du dich mit der Implementierung beschäftigt hast. Aber das ist bei Kapselung für Client-Code nicht nötig. Ich muß nur wissen, was gemacht wird, und nicht wie. Deshalb sind Funktionsnamen nur Schall und Rauch. Deshalb ist am Ende alles Setter/Getter.
    Auch die Size könnte nicht einfach nur aus return m_size; bestehen. Sie könnte auch stattdessen einfach alle Elemente on-the-fly durch zählen. Wäre zwar unperformant, aber ist es dann kein Getter mehr?


  • Mod

    Tachyon schrieb:

    SeppJ schrieb:

    Alle von dir genannten Funktionen machen sehr viel mehr als einfach nur Getter/Setter für Interna der Klasse zu sein.

    Der Sinn von Gettern ist doch nicht die bloße Rückgabe eines Wertes, sondern gerade dass man das Abfragen/Setzen eines Wertes mit einer Aktion oder Konvertierung verbinden kann und das diese Dinge vor dem Client verborgen bleiben.

    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.



  • Eben, Getter und Setter sind eben alles was einen abstrakten Zustand eines Objektes erfragt oder verändert (am besten in einem für die Anwender zweckdienlichen weg). Ein Objekt ohne Zustand wäre irgendwie sinnlos.
    Es sollte eher ein spezieller Name für Methoden erfunden werden, die wirklich nur einen Datenmember verändern und auslesen und somit die Interna nach außen tragen. Dazu könnte man dann nämlich sagen, was hier vorher so allgemeingültig falsch behauptet wurde.



  • SeppJ schrieb:

    Tachyon schrieb:

    SeppJ schrieb:

    Alle von dir genannten Funktionen machen sehr viel mehr als einfach nur Getter/Setter für Interna der Klasse zu sein.

    Der Sinn von Gettern ist doch nicht die bloße Rückgabe eines Wertes, sondern gerade dass man das Abfragen/Setzen eines Wertes mit einer Aktion oder Konvertierung verbinden kann und das diese Dinge vor dem Client verborgen bleiben.

    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.

    Wobei man hier anmerken muss, dass es sich auch so ergeben kann, dass dem so ist. Es ist kein Zeichen von schlechtem Design, nur weil die Getter und Setter trivial sind! Wenn ein gewisser Zustand nun eben sehr einfach in die übrige Modellierung des Objekts hineinpasst, warum sollte man sich da Sorgen machen und sich nicht einfach nur freuen?


  • Mod

    Artchi schrieb:

    SeppJ schrieb:

    Alle von dir genannten Funktionen (außer evtl. size und capacity) machen sehr viel mehr als einfach nur Getter/Setter für Interna des vectors zu sein.

    Und woher weißt du das? Doch nur weil du dich mit der Implementierung beschäftigt hast.

    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.

    capacity und size könnten Getter sein, weil die Anforderung an diese ist, dass sie einfach einen Wert zurückgeben. Da kann man nicht wissen, ob dieser Wert nicht als privater Member gespeichert wird (da weiß ich aus der Implementierung, dass dies oft nicht so ist, aber das ist egal da ich ja nicht bestreite, dass die beiden keine getter wären).

    Aber gerade push_back, reserve und resize sind Gegenbeipiele zu Settern.


  • Mod

    Decimad schrieb:

    Eben, Getter und Setter sind eben alles was einen abstrakten Zustand eines Objektes erfragt oder verändert (am besten in einem für die Anwender zweckdienlichen weg). Ein Objekt ohne Zustand wäre irgendwie sinnlos.
    Es sollte eher ein spezieller Name für Methoden erfunden werden, die wirklich nur einen Datenmember verändern und auslesen und somit die Interna nach außen tragen. Dazu könnte man dann nämlich sagen, was hier vorher so allgemeingültig falsch behauptet wurde.

    Ja, ich glaube, dass dies das Problem in diesem Thread ist. Verwirrung durch Mängel in der menschlichen Sprache.



  • 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 und resize 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 es real und imag 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!


Anmelden zum Antworten