Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Das ist doch hier total irrelevant und er hat Dich sogar explizit gebeten nicht solche Fallbeispiele zu verwenden. Bezieh Dich doch bitte einfach mal auf die Ausgangssituation. Die ist eben mit zwei identischen Operatoren, die auch keinerlei implizite Konvertierungen anbieten.Wie gesagt: Die Variante mit freien Funktionen unterstützt automatisch auch int + Vector2D, sobald Vector2D einen Konstruktor anbietet, der einen int nimmt, du brauchst nicht für alle möglichen Kombinationen separate Operatoren schreiben
Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von »BlueCobold« (06.02.2014, 07:26)
Der von dir verlinkte Artikel ist schön und gut und vor allem lang. Statt aber mal direkt zu sagen, warum mehr Member die Kapselung senken und non-member sie erhöhen, sagt er einfach, dass das so ist.
Und dem stimme ich nicht zu, denn Funktionalität, die von einer Klasse angeboten wird, sollte meiner Meinung nach (und das verstehe ich auch unter Kapselung) von dieser Klasse erledigt werden und nicht von freien Funktionen.
Freie Funktionen können weiß der Geier was für Funktionalität an Operatoren bieten, die die Klasse aber nicht so vorgesehen hat.
Z.B. kann ich für komplexe Zahlen eine Addition anbieten. Da gibt es aber nur eine sinnvolle Definition für in der Mathematik. Und diese sollte die Klasse auch abbilden und nicht zulassen, dass außerhalb jemand einen Operator hinpackt, der was ganz anderes anstellt.
Bzw. schön und gut, dass eine freie Funktion eine andere Addition anbietet, aber sie macht im Kontext der Klasse eventuell gar keinen Sinn.
Eine sinnvolle Implementierung des Operators wird aber aus meiner Sicht immer von der Klasse angeboten, denn diese weiß, was wirklich zu tun ist.
Die Antworten stellen immer eine ganz andere Ausgangssituation her, obwohl genau diese für die Frage aber relevant ist.
Warum macht man Globale Operatoren wenn beide Parameter der selben klasse Angehören?
Man könnte sogar noch weiter gehen und eine implizite Konvertierung hier sogar als Fehlerquelle bezeichnen.
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (06.02.2014, 11:21)
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Mir geht dabei gar keiner ab. Argumentum ad hominem?Was genau geht dir dabei ab?
Und das ist eben Unfug. Würde der Operator als Member anderen Code kaputt machen, wenn die Klasse geändert wird (und somit das Interface offenbar nicht mehr stimmt), wird dies genauso auch mit einer freien Funktion passieren, da diese ebenfalls vom Interface abhängt. Gewonnen habe ich also nichts. Im Gegenteil vielleicht sogar - es wird die freie Funktion durch menschliches Versagen nicht angepasst, weil sie einfach übersehen wurde, was bei einem Member vermutlich mit deutlich geringerer Wahrscheinlichkeit passiert wäre.(es wird aufgezeigt, wie sie einer Reduktion der Menge an Code, der durch Änderungen an der Klasse kaputtgeht, dienlich sein können)
Nein. Aber wenn ich eine Operation von string von vornherein vorsehe, dann ist ein Member ala "substring"[x,y] oder "charAt"==[] immer noch sinnvoller als eine freie Funktion dafür, die auf den chars des strings extern rumhantiert.Du bist also der Meinung, dass sämtliche Arten und Weisen, in der jemals jemand vielleicht einmal std::string würde verwenden wollen, am besten durch spezielle Memberfunktionen von std::string implementiert würden?
Finde ich prima. Da geht es ja darum fehlende Funktionalität zu ergänzen. Da macht eine freie Funktion ja auch wieder Sinn, weil es gar nicht anders geht. Wenn ich aber von Anfang an eine Klasse schreibe und dann im selben Zug auch noch Operationen dafür, dann brauche ich da keine Extension Method, sondern definiere einen Member. Falls es darum geht eine Operation auf mehreren Datentypen zu erstellen, die alle dasselbe Interface implementieren, dann ist - ganz offensichtlich - eine Extension Method oder freie Funktion dafür deutlich besser in der Lage als ein Member, der eben nur an eine einzelne Klasse gebunden ist. Das ist hier aber gar nicht das Thema.Wie stehst du eigentlich zu Extension Methods in C#?
Bitte? Das Interface der Klasse umfasst die freie Funktion gar nicht. Daher kann ich immer Dinge mit Operatoren auf Klassen tun, die total schwachsinnig sind. Wenn nicht, zeig mir eine Klasse, wo ich keinen freien Operator so definieren kann, dass er keinen Mist ausspuckt, obwohl das Interface der Klasse nicht "kaputt" ist.Dann ist das Interface der Klasse kaputt, denn es sieht offenbar die falsche Verwendung der Klasse vor.
Klar, kann ich. Und genau dort macht eine freie Funktion ja auch Sinn. Aber darüber diskutieren wir hier überhaupt nicht. Also du schon, die ganze Zeit. Koschi und ich aber nicht.Da hast du ein perfektes Beispiel gefunden. Ich kann reelle Zahlen und komplexe Zahlen addieren. Ich kann rationale Zahlen und komplexe Zahlen addieren. Ich kann ganze Zahlen und komplexe Zahlen addieren. Ich kann natürliche Zahlen und komplexe Zahlen addieren. Ich kann...
Total am Thema vorbei.Durch freie Funktionen kann ich einen entsprechenden operator + für komplexe Zahlen hinzufügen, ohne dass die Klassen für komplexe, reelle, rationale etc. Zahlen alle einander kennen und voneinander abhängig sein müssen...
Die freie Funktion hat mit der Klasse gar nichts zu tun. Und genau da ist das Problem. Klar kann ich viel ausrechnen, aber damit mache ich eben die Funktionsweise und mathematischen Operationen für komplexe Zahlen kaputt. Und das ist Schwachsinn.Wie gesagt: Eine Klasse, die es einem Benutzer ohne Anwendung physischer Gewalt erlaubt, die Klasse in Arten und Weisen zu verwenden, die im Kontext des durch die Klasse modellierten Konzepts keinen Sinn machen, ist eine schlechte Klasse. Der Fehler ist dann ganz eindeutig bei der Klasse zu suchen und nicht bei der freien Funktion.
Nein! Gott verdammt, du bist am Thema vorbei. Es geht hier NICHT um Interaktion von komplexen Zahlen mit anderen Datentypen. Sondern nur um die Interaktion ZWEITER IDENTISCHER DATENTYPEN.Siehe Beispiel mit komplexen Zahlen oben. Das würde bedeuten, dass jede Klasse von allen anderen Klassen, mit denen sie jemals interagieren soll, abhängig wird, da sie diese bereits in ihrem Interface erwähnen muss. Interaktion mit anderen Typen ist dann unmöglich, ohne alle beteiligten Klassen einander vorzustellen. Goodbye Kapselung, Erweiterbarkeit, Modularität, Flexibilität...
Nein, falsch. Das war ganz absichtlich perfekt so gewählt. Das ist genau der Punkt, über den hier gefragt wird. Alle anderen Möglichkeiten sind bekannt und erörtert worden. Aber nicht der Punkt, um den es hier explizit geht.Das von Koschi gebrachte Beispiel war etwas unglücklich gewählt, aber er konnte es ja nicht besser wissen...
DAS ist zumindest mal ein Ansatz einer Erklärung. Aber die wurde von Anfang an ja schon angedeutet. Man macht das eben so, weil es an gewissen anderen Stellen mehr Sinn ergibt - ob die nun hier zutreffen oder nicht. Es ist also schlicht eine Konsistenz-Entscheidung und man hätte es genauso auch andersrum entscheiden können.Und ich persönlich würde auch in solchen Fällen, wo es rein technisch egal ist, aus Gründen der Ästhetik die Implementierung als freie Funktion bevorzugen, einfach weil == konzeptionell eine symmetrische Operation ist und die Implementierung durch Memberfunktionen eine inhärente Asymmetrie aufweist...
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »BlueCobold« (06.02.2014, 12:05)
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Dass der Operator nicht versehentlich auf geschützte Attribute und Methoden der Parameter zugreifen kann und dadurch die Schnittstelle zerbricht. (Eigentlich das, was dot die ganze Zeit zu erklären versucht.)Warum macht man Globale Operatoren wenn beide Parameter der selben klasse Angehören?
als Beispiel diene hier mal etwas aus der Bekannten SFML
C-/C++-Quelltext
1 bool operator ==(const VideoMode& left, const VideoMode& right)
Also konkret gefragt welche Vorteile bringt diese Methode gegenüber der Implementierung als Member der Klasse?
Vielleicht sollten wir die Frage, die hier ursprünglich gestellt wurde, nochmal in Erinnerung rufen:
Warum macht man Globale Operatoren wenn beide Parameter der selben klasse Angehören?
Das von Koschi gebrachte Beispiel war etwas unglücklich gewählt, aber er konnte es ja nicht besser wissen...
Zitat von »Krishty«
Dass der Operator nicht versehentlich auf geschützte Attribute und Methoden der Parameter zugreifen kann und dadurch die Schnittstelle zerbricht. (Eigentlich das, was dot die ganze Zeit zu erklären versucht.)
Was verstehst du unter Lösung? Was ist das Problem?Also im Idealfall sind die Member einer Klasse alle private (Das verstehe ich unteranderem unter Kapselung). So kann ein Globaler Operator eigentlich schon gar nicht mehr auf die Member einer Klasse zu greifen. Die Lösung hier für, man macht eine friend-Funktion, diese wiederum hat zugriff auf alle Member einer Klasse.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Werbeanzeige