Ich habe gelesen, dass ein überladener Operator, der als Member-Funktion deklariert wurde, asymmetrisch ist, weil er nur einen Parameter haben kann und der andere Parameter automatisch den 'This' -Zeiger übergeben wird. Es gibt also keinen Standard, um sie zu vergleichen. Auf der anderen Seite ist der überladene Operator, der als Freund deklariert wurde, symmetrisch, weil wir zwei Argumente des gleichen Typs übergeben und daher können sie verglichen werden. Meine Frage ist, dass, wenn ich den lvalue eines Zeigers mit einer Referenz vergleichen kann, warum sind Freunde bevorzugt? (Bei Verwendung einer asymmetrischen Version werden dieselben Ergebnisse erzielt wie bei symmetrischen Versionen) Warum verwenden STL-Algorithmen nur symmetrische Versionen?Operatorüberladung: Member-Funktion vs. Nicht-Member-Funktion?
Antwort
Wenn Sie Ihre Operatorüberladene Funktion als Elementfunktion definieren, übersetzt der Compiler Ausdrücke wie s1 + s2
in s1.operator+(s2)
. Das bedeutet, dass die überladene Mitgliedsfunktion des Operators auf dem ersten Operanden aufgerufen wird. So funktionieren Mitgliederfunktionen!
Aber was ist, wenn der erste Operand keine Klasse ist? Es gibt ein großes Problem, wenn wir einen Operator überladen wollen, bei dem der erste Operand kein Klassentyp ist, sondern double
. So kann man nicht so schreiben 10.0 + s2
. Sie können jedoch eine Operator-überladene Elementfunktion für Ausdrücke wie s1 + 10.0
schreiben.
diese Bestellung Problem zu lösen, definieren wir Betreiber überladene Funktion als friend
IF es private
Mitglieder zugreifen muss. Machen Sie es nur friend
, wenn es auf private Mitglieder zugreifen muss. Ansonsten einfach Nicht-Freund Nicht-Mitglied Funktion zu Verbesserung Verkapselung!
class Sample
{
public:
Sample operator + (const Sample& op2); //works with s1 + s2
Sample operator + (double op2); //works with s1 + 10.0
//Make it `friend` only when it needs to access private members.
//Otherwise simply make it **non-friend non-member** function.
friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}
Lesen Sie diese:
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation
„Make' es friend' nur dann, wenn es privat members..and zugreifen muss, wenn Sie nicht über/gebohrt des Schreibens Accessoren, rechts – badmaash
@Abhi: Wählen Sie Ihre Wahl: Verbesserte Encapsulation vs Faule Gewohnheit zu schreiben – Nawaz
gibt es bekannte Fälle, in denen Sie mit dem globalen 'Operator +()' einfach sein 'return op2.operator + (op1) nicht nur das' friend' Stichwort vermeiden könnten; 'In beiden Fällen + standardmäßig würden den Eingangsabtastwert nicht ändern, und? stattdessen zurückgeben eine neue rvalue Instanz von 'Sample', nicht wahr? – matthias
Es ist nicht unbedingt eine Unterscheidung zwischen friend
Betreiber Überlastungen und Memberfunktion Betreiber Überlastungen, wie es zwischen globalen Betreiber Überlastungen und Memberfunktion Betreiber Überlastung ist.
Ein Grund eine globalen Betreiber Überlastung zu bevorzugen ist, wenn Sie wollen Ausdrücke ermöglichen, wo der Klassentyp auf der Seite eines Binäroperators rechts erscheint. Zum Beispiel:
Foo f = 100;
int x = 10;
cout << x + f;
Dies funktioniert nur, wenn es eine globale Betreiber Überlastung ist für
Foo operator + (int x, const Foo & f);
Beachten Sie, dass die globale Bedienerüberlastung nicht notwendigerweise eine friend
Funktion sein muss. Dies ist nur notwendig, wenn es Zugriff auf private Mitglieder von Foo
benötigt, aber das ist nicht immer der Fall.
Unabhängig davon, ob Foo
hatte nur einen Betreiber Überlastung Memberfunktion, wie:
class Foo
{
...
Foo operator + (int x);
...
};
... dann würden wir nur in der Lage sein, Ausdrücke zu haben, wo eine Foo
Instanz auf den erscheint links des Plus Operator.
+ 1 für die Unterscheidung zwischen Elementfunktionen und Dritt Funktionen machen anstatt Mitglied und Freund Funktionen. Ich denke heute würden wir sagen "Global oder Namespace Scope". –
- 1. Operatorüberladung
- 2. Operatorüberladung (Freundes- und Mitgliedsfunktion)
- 3. Operatorüberladung C++
- 4. Operatorüberladung für Max in C++
- 5. Aufruf `this` Memberfunktion von generic Lambda - Klirren vs gcc
- 6. _beginthreadex statische Memberfunktion
- 7. SFINAE Memberfunktion Existenztest Ausgabe
- 8. const-Referenz qualifizierte Memberfunktion
- 9. Verschieben Memberfunktion Generation
- 10. Forwarding Argumente Template-Memberfunktion
- 11. wenn klassenspezifische Memberfunktion hat
- 12. Anzahl der Argumente in Operatorüberladung in C++
- 13. Operatorüberladung und Linq-Summe in C#
- 14. C++ Operatorüberladung [] für lvalue und rvalue
- 15. Verwenden Memberfunktion in std :: packaged_task
- 16. PHP Aufruf zur Memberfunktion ToXml
- 17. Python - argmin/argmax für Memberfunktion
- 18. Konst Memberfunktion und typedef, C++
- 19. Starten eines Threads aus einer Memberfunktion während der Memberfunktion einer anderen Klasse
- 20. Kopierkonstruktor und Operatorüberladung in C++: Ist eine gemeinsame Funktion möglich?
- 21. C++ Operatorüberladung für eine Matrixklasse mit reellen und komplexen Matrizen
- 22. Wie verkette ich zwei einfach verkettete Listen über Operatorüberladung?
- 23. Mehrdeutige Zugriff auf Basisklasse Template-Memberfunktion
- 24. Rückgabewert von einer boost :: threaded Memberfunktion?
- 25. Aufruf einer Memberfunktion errorInfo() on String
- 26. Aufruf einer Memberfunktion eines geerbten Vektorelements
- 27. Aufruf an eine Memberfunktion execute() on boolean
- 28. Schwerwiegender Fehler: Aufruf einer Memberfunktion getKeyName()
- 29. Kann eine Klasse eine Memberfunktion haben?
- 30. Geben eines Template-Memberfunktion in eine Vorlage
Ihre Frage ist wirklich nur um binäre Operatoren. Nicht alle überladenen Operatoren sind auf einen einzelnen Parameter beschränkt. Der Operator() kann eine beliebige Anzahl von Parametern annehmen. Unäre Operatoren können dagegen keine Parameter haben. –
http://stackoverflow.com/a/4421729/103167 –
Dies ist eines von vielen Themen in dem überdachten [C++ FAQ: Betreiber Überlastung] (http://stackoverflow.com/questions/4421706/operator-overloading) –