Operator Überladung
-
Wahrscheinlich willst du darauf hinaus, dass der
operator<auf private Membervariablen zugreift (hierival) und deswegen einfriendder Klasse sein muss. Allerdings ist das nicht nötig, wenn die KlasseAsauber gekapselt ist und Get-Methoden fürivalanbietet. Ich rate dir zu diesem Schritt.
-
Aber wenn ich das als Klassenmethode definiere kann ich doch auf die Privaten Elemente zugreifen, oder etwa nicht?
-
Ja, aber der
operator<sollte besser global sein. Im Artikel über Operatorüberladung steht auch wieso. Den würde ich unbedingt mal durchlesen, er enthält sehr viele Tipps und Best Practices.Die Frage ist: Brauchst du überhaupt Zugriff auf private Membervariablen? Denn wenn ein Getter sowieso angebracht ist, warum nicht diesen nutzen?
-
Gut den Artikel werde ich mir durchlesen. Aber wieso get, wenn ich die Überladung als Klassenmethode mache?
-
OOP Anäfnger schrieb:
Aber wieso get, wenn ich die Überladung als Klassenmethode mache?
Du machst die Operatorüberladung nicht als Klassenmethode.
-
Macht man die Überladung nicht in den Public Bereich der Klasse?
-
OOP Anfänger schrieb:
Macht man die Überladung nicht in den Public Bereich der Klasse?
Nein, du machst sie global (hier für den Fall des
operator<, je nach Operator siehts ein wenig anders aus). Aber lies doch den Artikel, dort wird das alles erklärt!
-
OOP Anfänger schrieb:
Macht man die Überladung nicht in den Public Bereich der Klasse?
Steht in dem Artikel.
Trägt unter anderem zur Symmetrie des Operators bei.
-
Also gilt das nur bei den Vergleichsoperatoren, dass man diese als globale Funktion überladen sollte. Den Zuweisungsoperator zum Beispiel macht man ja trotzdem als Klassenmethode, oder?
-
OOP Anfänger schrieb:
Also gilt das nur bei den Vergleichsoperatoren, dass man diese als globale Funktion überladen sollte.
Nein -> Artikel lesen!
-
Ja und evlt noch bei anderen. Ich habe mir den Artikel noch nicht ganz durchgelesen.
-
Allerdings ist das nicht nötig, wenn die Klasse A sauber gekapselt ist und Get-Methoden für ival anbietet. Ich rate dir zu diesem Schritt.
Ich rate nicht zu diesem Schritt, wenn durch die get/set-Methoden kein Mehrwert ausserhalb der Klasse erreicht wird. Mittels friend oeffne ich explizit fuer diese Funktion den private-Bereich. Mittels get/set oeffne ich fuer alle anderen den private-Bereich.
-
knivil schrieb:
Allerdings ist das nicht nötig, wenn die Klasse A sauber gekapselt ist und Get-Methoden für ival anbietet. Ich rate dir zu diesem Schritt.
Ich rate nicht zu diesem Schritt, wenn durch die get/set-Methoden kein Mehrwert ausserhalb der Klasse erreicht wird. Mittels friend oeffne ich explizit fuer diese Funktion den private-Bereich. Mittels get/set oeffne ich fuer alle anderen den private-Bereich.
Ähnliche Diskussion zu einem anderen Operator siehe auch hier - ich würde hier wie auch im op<< - Fall weder zur friend-deklaration noch zu allgemeingültigen Gettern raten, sondern eine Methode anbieten die die eigentliche Arbeit des op< übernimmt:
class C : public boost::less_than_comparable<C> { public: bool lessThan(C const& other) const { /* Zugriff auf private Daten */ } }; inline bool operator < (C const& lhs, C const& rhs) { return lhs.lessThan(rhs); }
-
knivil schrieb:
Ich rate nicht zu diesem Schritt, wenn durch die get/set-Methoden kein Mehrwert ausserhalb der Klasse erreicht wird.
In vielen Fällen entsteht ein Mehrwert, weil eine öffentliche Eigenschaft verglichen wird, also sowieso entsprechende Get- und Set-Methoden notwendig sind. Aber der Einwand ist natürlich berechtigt.
pumuckl schrieb:
ich würde hier wie auch im op<< - Fall weder zur friend-deklaration noch zu allgemeingültigen Gettern raten, sondern eine Methode anbieten die die eigentliche Arbeit des op< übernimmt:
class C : public boost::less_than_comparable<C> { public: bool lessThan(C const& other) const { /* Zugriff auf private Daten */ } };Nun ja, man kanns auch übertreiben. Wenn du dieses Konzept konsequent durchziehst, landest du bei Java-Konstrukten wie
a.equals(b)odera.compareTo(b). Und zwar zusätzlich zu den freien Funktionen – das ist ja das Schlimme. In Java ist sind solche Methoden okay, weil es keine freien Funktionen oder Operatoren gibt. Aber in C++? Welchen Mehrwert bringtlessThan()? Man muss mehr Code schreiben, hat eine asymmetrische Methode mit zusätzlicher Indirektion und bietet zwei Funktionen für den genau gleichen Zweck an. Rechtfertigt das Vermeiden vonfriendwirklich diese Nachteile?Wie schon im verlinkten Thread angedeutet: Man kann mit dem Versuch, die Kapselung zu erhöhen, das genaue Gegenteil erreichen. Zumindest wenn man Kapselung nicht nur durch formale Aspekte wie "ist Memberfunktion der Klasse" definiert, sondern durch semantische ("hat Zugriff auf private Member"). Den Ansatz, Schnittstellen nicht unnötig aufzublähen, sehe ich nämlich als wichtigen Bestandteil dieses Konzepts an.
Nur, damit ich nicht missverstanden werde: Ich finde es durchaus gut, wenn eine Klasse weitgehend für sich selbst zuständig ist, und will
friendkeinesfalls verharmlosen. Es ist ein Sprachmittel, das mit Bedacht eingesetzt und wenn sinnvoll möglich vermieden werden soll. In vielen Fällen (z.B.operator+=undoperator+) geht das auch sehr elegant. Aber meiner Meinung nach ist eine kategorische Abneigung gegen Sprachmittel wiefriendnicht unbedingt förderlich, wenn es ums Design einer Klassenschnittstelle geht. Denn erst durch die Kombination der verschiedenen Möglichkeiten kommt das volle Potenzial einer Programmiersprache zur Geltung.