Variablen in eigenem Projekt private machen?
-
Warum so böse
?
Ich frage mich nur was ich machen soll, weil im Endeffekt ist Get und Set doch auch das gleiche wie public.
Du meinst also ich soll den üblichen Stil konsequent durchziehen?
-
Hi,
Get/Set erhöht die Kapselung, es kann später vielleicht sein, dass du statt einer Variablen einen festen Wert hast oder etwas Bestimmtes gar nicht direkt aus einer Variablen kommt, sondern aus bestehenden berechnet werden muss.
In diesem Fall muss nicht der gesamte Code umgeschrieben werden, sondern nur eben diese Funktion.
Was die Klasse dabei intern mit dem Wert zu tun hat, ist dabei völlig irrelevant und sollte dem Benutzer eigentlich auch nicht klar sein, daher sind Get- und Setmethoden besser.MfG Eisflamme
-
Hallo,
neben der Frage ob public oder private + set/get würde ich mir vorallem erstmal die Frage stellen, warum du überhaupt auf die Variablen zugreifen musst und ob die Variablen nicht in der falschen Klasse untergebracht sind.
Natürlich sind public-Variablen in echten Klassen großer Käse (in puren Datencontainern die nichts zu verbergen haben sind sie harmlos), aber private + get/set ist auch nicht gerade der Weißheit letzter Schluss. Du hast zwar den Vorteil, dass du den Zugriff noch kontrollieren kannst, von Information Hiding kann man in diesem Zusammenhang aber kaum noch sprechen.
-
-ratlos- schrieb:
Ich frage mich nur was ich machen soll, weil im Endeffekt ist Get und Set doch auch das gleiche wie public.
Nein, ist es nicht. Und solange C++ keine Properties anbietet, sind für sowas get/set Methoden vorzuziehen. Du musst sie ja nicht get.../set... nennen, wenn dir das unsympatisch ist.
-
Datenelemente sind privat, ansonsten macht das ganze Kapseln der OOP keinen Sinn.
Stell dir vor, du hast eine Klasse Teilchen und willst den Impuls eines Teilchens abfragen. Dann könntest du z.B. eine Member-Variable impuls_ in der Klasse vorsehen. Später sagst du vielleicht, ach das mache ich mittels masse_*geschwindigkeit_ anstelle impuls, dann ist eine get-/set-Funktion sehr wertvoll:
vorher: double getImpuls () { return impuls_;}
nachher: double getImpuls () { return masse_*geschwindigkeit_;}Wenn du nun an vielen Stellen die Variable impuls (public) benutzt hättest, käme viel sinnlose und fehleranfällige Arbeit auf dich zu. Ähnliches gilt für die set-Funktion.
HumeSikkins schlägt dir zusätzlich vor, verstärkt über "information hiding" (das ist mehr als nur encapsulation) nachzudenken. Encapsulation ist nur eine Möglichkeit, die C++ u.a. OOP-Sprachen bieten, information hiding dagegen ein design principle.
Hiding data is not the full extent of information hiding. David Parnas first introduced the concept of information hiding around 1972. He argued that the primary criteria for system modularization should concern the hiding of critical design decisions. He stressed hiding "difficult design decisions or design decisions which are likely to change." Hiding information in that manner isolates clients from requiring intimate knowledge of the design to use a module, and from the effects of changing those decisions.
Wenn du z.B. einen Punkt intern kartesisch darstellst und später auf Polarkoordinaten wechseln willst, dann sollte sich das Interface nicht ändern müssen. Es geht also um die Reduktion von Abhängigkeiten.
-
Ich würde mal einen anderen Punkt auch reinbringen: Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Ok im Fall der Maus wird das so oft nicht aufgerufen, sodass das notwendig wäre, aber es gibt Situationen, in denen ein Ständiger funktionsaufruf, z.B. in Schleifen, kosten kann.
Generell ist aber natürlich der Kapselung vorrang zu geben.
-
randa schrieb:
Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Nein.
-
randa schrieb:
Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Wozu gibt es inline?
-
randa schrieb:
Ich würde mal einen anderen Punkt auch reinbringen: Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Da es generell eine kluge Idee ist, solch kleine Funktionen inline zu machen, bekommst du auch keine Performance Penalty.
-
Ich kenne inline, doch es ist nicht das gleiche wie der direkte Zurgiff. Abgesehen davon kann man größere Funktionen nicht inline machen.
Edit: Damit da klar ist: Ich rede nur von extremfällen in der Grafikprogrammierung, z.B. in der inneren Schleife der Rasterisierung o.ä. Ich sagte bereits, das natürlich eine Kapselung normalerweise vorzuziehen wäre.
-
Extreme Fälle erfordern manchmal extreme Lösungen. Bringen diese Vorteile, sollte man sie nutzen. Das hat aber nichts mit allgemeinen Design-Prinzipien zu schaffen.
-
randa schrieb:
Ich kenne inline, doch es ist nicht das gleiche wie der direkte Zurgiff. Abgesehen davon kann man größere Funktionen nicht inline machen.
Zu 1: Wenn da nur ein return var; drin steht wird es auch später im Programm nicht mehr sein, als ein klasse.var bzw. einfach die Adresse der Variablen.
Zu 2: Mein Compiler kann es z.B. mit __forceinline statt dem normalen inline, andere Compiler bieten es sicher auch an
-
Erhard Henkes schrieb:
Extreme Fälle erfordern immer extreme Lösungen. Bringen diese Vorteile, sollte man sie nutzen. Das hat aber nichts mit allgemeinen Design-Prinzipien zu schaffen.
Das habe ich ja auch nicht behauptet. Ich sagte: In einigen Fällen, in denen es Performance bringt, sollte man in Betracht ziehen, einen Direkten Zugriff zu ermöglichen.
-
randa schrieb:
Ich kenne inline, doch es ist nicht das gleiche wie der direkte Zurgiff. Abgesehen davon kann man größere Funktionen nicht inline machen.
Edit: Damit da klar ist: Ich rede nur von extremfällen in der Grafikprogrammierung, z.B. in der inneren Schleife der Rasterisierung o.ä. Ich sagte bereits, das natürlich eine Kapselung normalerweise vorzuziehen wäre.
Wenn mit deinem Compiler zwischen type.var und type.get_var() (wenn get_var inline ist), in der release version, auch nur ein Processordurchlauf Unterschied gibt dann schmeiß ihn sofort in die digitale Mülltonne.
-
randa: Es geht nicht darum, dass inline annähernd so schnell wie ein direkter Zugriff ist, sondern *genau so* schnell. Da ist es egal, ob das Objekt für Benutzereingaben oder in einer 3D-Engine verwendet wird; gleich schnell ist gleich schnell.
randa schrieb:
Abgesehen davon kann man größere Funktionen nicht inline machen.
Äh, stimmt? Wenn du getX() mit einem direkten Zugriff vergleichen willst, ist getX() ja per Definition nicht groß. Und wenn es groß sein sollte, fällt der direkte Zugriff eh raus.
Natürlich ist getX() nicht ganz so flexibel wie ein direkter Zugriff - man kann das zu Grunde liegende Feld nicht per Referenz an andere Funktionen übergeben usw. - aber davon war hier IMHO nicht die Rede.
-
Wenn du die Klasse nicht benutzt kanst du die Variabel ruhgen Gewissens public machen. Das Konzept ist für den normalsterblichen Hobbyprogrammierer sowieso etwas überdiemensioniert. Ich würde mal sagen wenn du weniger als 200 Zeilen Code (ohne die Klasse!) hast kannst du dir das Konzept schenken in dem Fall spielts wirklich keine Geige. Der ganze Code liegt später sowieso nur kompeliert vor (kann nicht mehr eingesehen werden). Wenn die Klasse also wirklich nur für dich ist ist es völlig egal, mach das was dir besser gefällt.
Lass dich von keinem hier von der Aussage beeindrucken "Das ist schlechter Stil" oder "das macht man nicht". Wie so oft führen viele Wege nach Rom. Solange es keinen Performancetechnischen Unterschied macht kanst du auch noch ganz andere Sachen machen.
Ein Freund von mir benutzt in seinen Klassen Konstanten die im Hauptquelltext definiert werden müssen. (<- da sage selbst ich "das geht eigentlich so nicht"), aber ihm ist das völlig egal und die Klasse die er so gemacht ist wirklich gut!
-
flammenvogel schrieb:
Lass dich von keinem hier von der Aussage beeindrucken "Das ist schlechter Stil" oder "das macht man nicht". Wie so oft führen viele Wege nach Rom. Solange es keinen Performancetechnischen Unterschied macht kanst du auch noch ganz andere Sachen machen.
schlechter stil wird durchaus zum problem sobald im team gearbeitet wird
aber zum thema möcht ich noch zwei punkte beisteuern
1. wenn es vollkommen egal ist welchen wert die mausposition hat könntest dus natürlich auch public machen
in einer set funktion hast du aber noch die möglichkeit die position zu kontolliern und abzuändern2. falls irgendwann ungültige werte gesetzt werden, kannst du in ner set funktion leichter per bedingtem breakpoint prüfen von wem der wert gesetzt wird.
falls die variable public is müsstest du halt einen breakpoint auf die speicheradresse setzen
-
"Das ist schlechter Stil" oder "das macht man nicht".
Hier wurde nicht in diesem Sinne argumentiert, sondern vielfach klare und nachvollziehbare Argumente vorgebracht. Hat man bessere Argumente, kann man diese ja nennen. Bisher habe ich jedoch noch kein stichhaltiges Argument gelesen, um eine Member-Variable public zu gestalten. Auch das Performance-Argument sticht nicht.
-
Erhard Henkes schrieb:
"Das ist schlechter Stil" oder "das macht man nicht".
Hier wurde nicht in diesem Sinne argumentiert, sondern vielfach klare und nachvollziehbare Argumente vorgebracht. Hat man bessere Argumente, kann man diese ja nennen. Bisher habe ich jedoch noch kein stichhaltiges Argument gelesen, um eine Member-Variable public zu gestalten. Auch das Performance-Argument sticht nicht.
Hey, ich sagte ja schon, ihr habt recht
Ehrlich gesagt hab ich mich hier auf einige Bereiche der Grafikprogrammierung bezogen, da ich vor ein paar Wochen genau dieses Problem hatte, und mich entschieden hab, es public zu machen. Aus dem Einfachen Grund weil ich in einer Inneren Schleife Zugriff auf mehrere Variablen einer Klasse brauchte.
-
Hey, ich sagte ja schon, ihr habt recht.
o.k.
Teste doch mal genau dieses Beispiel mit get-Funktionen (inline), damit du siehst, dass es wirklich kein Nachteil ist.
Aber den Schwerpunkt sollte man im "information hiding" sehen.