Ich habe gelesen, dass ein überladener Operator, der als Elementfunktion deklariert ist, asymmetrisch ist, da er nur einen Parameter haben kann und der andere Parameter, der automatisch übergeben wird, der this
Zeiger ist. Es gibt also keinen Standard, um sie zu vergleichen. Auf der anderen Seite, überladener Operator deklarierte als friend
ist symmetrisch , weil wir zwei Argumente des gleichen Typs übergeben , und daher können sie verglichen werden.
Meine Frage ist, warum Freunde bevorzugt werden, wenn ich den Wert eines Zeigers immer noch mit einer Referenz vergleichen kann? (Die Verwendung einer asymmetrischen Version führt zu denselben Ergebnissen wie die symmetrische Version.) Warum verwenden STL-Algorithmen nur symmetrische Versionen?
Antworten:
Wenn Sie Ihre vom Operator überladene Funktion als Elementfunktion definieren, übersetzt der Compiler Ausdrücke wie
s1 + s2
ins1.operator+(s2)
. Das heißt, die vom Operator überladene Elementfunktion wird beim ersten Operanden aufgerufen. So funktionieren Mitgliedsfunktionen!Aber was ist, wenn der erste Operand keine Klasse ist? Es gibt ein großes Problem, wenn wir einen Operator überladen möchten, bei dem der erste Operand kein Klassentyp ist
double
. Sie können also nicht so schreiben10.0 + s2
. Sie können jedoch eine vom Operator überladene Elementfunktion für Ausdrücke wie schreibens1 + 10.0
.Um dieses Ordnungsproblem zu lösen, definieren wir eine überladene Funktion des Operators als
friend
WENN sie aufprivate
Mitglieder zugreifen muss . Machen Sie esfriend
NUR, wenn es auf private Mitglieder zugreifen muss. Andernfalls machen Sie es einfach zu einer Nicht-Freund-Nicht-Mitglied- Funktion, um die Kapselung zu verbessern !Lesen Sie diese:
Ein kleines Problem bei der Reihenfolge in Operanden
Wie Nicht-Mitglieder-Funktionen die Kapselung verbessern
quelle
friend
nur, wenn es auf private Mitglieder zugreifen muss ... und wenn Sie nicht gelangweilt sind / sind, Accessoren zu schreiben, richtig?a/b
.friend
besteht darin, sie in Bezug auf die Operatoren für die Zuweisung von Operationen (die mit ziemlicher Sicherheit öffentliche Mitglieder sein werden) zu implementieren. Sie können beispielsweiseT T::operator+=(const T &rhs)
als Mitglied definieren und dann NichtmitgliedT operator(T lhs, const T &rhs)
als definierenreturn lhs += rhs;
. Die Nichtmitgliedsfunktion sollte im selben Namespace wie die Klasse definiert werden.Es ist nicht unbedingt eine Unterscheidung zwischen
friend
Operatorüberladungen und Elementfunktionsoperatorüberlastungen, sondern zwischen globalen Operatorüberladungen und Elementfunktionsoperatorüberlastungen.Ein Grund, eine globale Operatorüberladung zu bevorzugen, besteht darin, Ausdrücke zuzulassen, bei denen der Klassentyp auf der rechten Seite eines binären Operators angezeigt wird . Beispielsweise:
Dies funktioniert nur, wenn eine globale Operatorüberlastung für vorliegt
Beachten Sie, dass die globale Operatorüberladung nicht unbedingt eine
friend
Funktion sein muss. Dies ist nur erforderlich, wenn Zugriff auf private Mitglieder von erforderlichFoo
ist, dies ist jedoch nicht immer der Fall.Unabhängig davon, wenn
Foo
nur ein Elementfunktionsoperator überlastet wäre, wie:... dann könnten wir nur Ausdrücke haben, bei denen eine
Foo
Instanz links vom Plus-Operator erscheint.quelle