Die offensichtlichen Beispiele für eine angemessene Überladung von Operatoren sind Klassen, die sich genauso verhalten wie Zahlen. So BigInt Klassen (wie Jalayn schon sagt), komplexe Zahlen oder Matrix - Klassen (wie Superbest schon sagt) alle die gleichen Operationen haben , dass gewöhnliche Zahlen so wirklich gut auf mathematischen Operatoren Karte haben, während der Zeit - Operationen (wie vorgeschlagen svick ) schön auf eine Teilmenge der Karte dieser Operationen.
Etwas abstrakter könnten Operatoren verwendet werden, wenn set-ähnliche Operationen ausgeführt werden, also operator+
eine Vereinigung , operator-
eine Ergänzung usw. Dies erweitert jedoch das Paradigma, insbesondere wenn Sie den Additions- oder Multiplikationsoperator für eine Operation verwenden, die nicht ' t kommutativ , wie Sie vielleicht erwarten.
C # selbst bietet ein hervorragendes Beispiel für das Überladen nicht numerischer Operatoren. Es verwendet +=
und -=
, um Delegierte hinzuzufügen und zu subtrahieren , dh sie zu registrieren und die Registrierung aufzuheben. Dies funktioniert gut, da die Operatoren +=
und so -=
funktionieren, wie Sie es erwarten würden, und dies führt zu wesentlich präziserem Code.
Für den Puristen ist eines der Probleme mit dem String- +
Operator, dass er nicht kommutativ ist. "a"+"b"
ist nicht dasselbe wie "b"+"a"
. Wir verstehen diese Ausnahme für Strings, weil sie so häufig vorkommt, aber wie können wir feststellen, ob die Verwendung operator+
für andere Typen kommutativ ist oder nicht? Die meisten Menschen gehen davon aus, dass dies der Fall ist, es sei denn, das Objekt ist stringartig , aber Sie wissen nie wirklich, was die Menschen davon ausgehen.
Wie bei Saiten sind auch bei Matrizen die Schwächen bekannt. Es ist offensichtlich, dass Matrix operator* (double, Matrix)
es sich um eine Skalarmultiplikation handelt, wohingegen Matrix operator* (Matrix, Matrix)
es sich beispielsweise um eine Matrixmultiplikation (dh eine Matrix aus Skalarmultiplikationen) handeln würde .
In ähnlicher Weise ist die Verwendung von Operatoren mit Delegierten so weit von der Mathematik entfernt, dass Sie diese Fehler wahrscheinlich nicht machen werden.
Im Übrigen an der 2011 ACCU Konferenz , Roger Orr & Steve Liebe präsentiert eine Sitzung auf einige Objekte als andere gleich sind - ein Blick auf die vielen Bedeutungen der Gleichheit, der Wert und Identität . Ihre Folien können heruntergeladen werden , ebenso wie der Anhang von Richard Harris zur Gleitkomma-Gleichheit . Fazit: Sei sehr vorsichtig mit operator==
, hier seid Drachen!
Das Überladen von Operatoren ist eine sehr leistungsfähige semantische Technik, die jedoch leicht zu überbeanspruchen ist. Idealerweise sollten Sie es nur in Situationen verwenden, in denen aus dem Kontext klar hervorgeht, wie sich ein überladener Operator auswirkt. In vielerlei Hinsicht a.union(b)
ist klarer als a+b
, und a*b
ist viel dunkler als a.cartesianProduct(b)
, zumal das Ergebnis eines kartesischen Produktes SetLike<Tuple<T,T>>
eher ein a als ein a wäre SetLike<T>
.
Die wirklichen Probleme beim Überladen von Operatoren treten auf, wenn ein Programmierer davon ausgeht, dass sich eine Klasse auf die eine oder andere Weise verhält. Ich schlage vor, dass diese Art von semantischem Konflikt vermieden werden sollte.