Überladen von Operatoren: Member-Funktion vs. Nicht-Member-Funktion?

Lesezeit: 4 Minuten

Uberladen von Operatoren Member Funktion vs Nicht Member Funktion
badmaash

Ich habe gelesen, dass ein überladener Operator als Member-Funktion deklariert ist asymmetrisch weil es nur einen Parameter haben kann und der andere Parameter automatisch übergeben wird this Zeiger. Es gibt also keinen Standard, um sie zu vergleichen. Andererseits wird der überladene Operator als a deklariert friend ist symmetrisch weil wir zwei Argumente des gleichen Typs übergeben und sie daher verglichen werden können.

Meine Frage ist, warum Freunde bevorzugt werden, wenn ich immer noch den lvalue eines Zeigers mit einer Referenz vergleichen kann? (Die Verwendung einer asymmetrischen Version ergibt die gleichen Ergebnisse wie eine symmetrische) Warum verwenden STL-Algorithmen nur symmetrische Versionen?

  • Ihre Frage bezieht sich wirklich nur auf binäre Operatoren. Nicht alle überladenen Operatoren sind auf einen einzigen Parameter beschränkt. Der ()-Operator kann eine beliebige Anzahl von Parametern annehmen. Unäre Operatoren hingegen können keine Parameter haben.

    – Karl Salvia

    7. Januar 2011 um 4:16 Uhr

  • stackoverflow.com/a/4421729/103167

    – Ben Voigt

    19. Februar 2012 um 1:09 Uhr

  • Dies ist eines von vielen Themen, die in den häufig gestellten Fragen zu C++ behandelt werden: Überladen von Operatoren

    – Ben Voigt

    19. Februar 2012 um 1:09 Uhr


Uberladen von Operatoren Member Funktion vs Nicht Member Funktion
Nawaz

Wenn Sie Ihre mit dem Operator überladene Funktion als Member-Funktion definieren, übersetzt der Compiler Ausdrücke wie s1 + s2 hinein s1.operator+(s2). Das heißt, die mit dem Operator überladene Elementfunktion wird für den ersten Operanden aufgerufen. So funktionieren Mitgliederfunktionen!

Was aber, 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 sagen wir double. So kann man also nicht schreiben 10.0 + s2. Sie können jedoch eine mit Operatoren überladene Elementfunktion für Ausdrücke wie schreiben s1 + 10.0.

Um dies zu lösen Bestellung Problem, wir definieren eine operatorüberladene Funktion als friend WENN es zugreifen muss private Mitglieder. Mach es friend NUR wenn auf private Mitglieder zugegriffen werden muss. Ansonsten einfach machen Nicht-Freund Nicht-Mitglied Funktion zu verbessern 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
}

Lese das :
Ein kleines Problem beim Sortieren von Operanden
Wie Nicht-Member-Funktionen die Kapselung verbessern

  • “Mach es friend nur wenn es auf private Mitglieder zugreifen muss … und wenn Sie nicht gelangweilt sind, Accessoren zu schreiben, richtig?

    – badmaash

    7. Januar 2011 um 5:15 Uhr

  • @Abhi: Wählen Sie Ihre Wahl: Verbesserte Kapselung vs. faule Schreibgewohnheiten!

    – Nawaz

    7. Januar 2011 um 5:17 Uhr


  • @matthias, nicht alle Operatoren sind kommutativ. Einfaches Beispiel ist a/b.

    – edA-qa mort-ora-y

    25. April 2012 um 7:31 Uhr

  • Eine gängige Methode, um zu vermeiden, dass Ihre Nichtmitgliedsbetreiber dies verlangen friend besteht darin, sie in Bezug auf die Operationszuweisungsoperatoren zu implementieren (die mit ziemlicher Sicherheit öffentliche Mitglieder sein werden). Sie könnten beispielsweise definieren T T::operator+=(const T &rhs) als Mitglied und definieren Sie dann Nichtmitglied T operator(T lhs, const T &rhs) als return lhs += rhs;. Die Nicht-Member-Funktion sollte im selben Namespace wie die Klasse definiert werden.

    – Adrian McCarthy

    10. August 2016 um 18:58 Uhr

  • @ricky: Aber wenn die linke Seite eine Kopie ist (wie in meinem Kommentar), spielt die Tatsache, dass sich die linke Seite ändert, keine Rolle.

    – Adrian McCarthy

    19. November 2018 um 21:57 Uhr

1647105007 1 Uberladen von Operatoren Member Funktion vs Nicht Member Funktion
Karl Salvia

Es ist nicht unbedingt eine Unterscheidung zwischen friend Operatorüberladungen und Elementfunktionsoperatorüberladungen, wie sie zwischen liegen global Operatorüberladungen und Memberfunktionsoperatorüberladungen.

Ein Grund, a global Die Operatorüberladung ist, wenn Sie Ausdrücke zulassen möchten, in denen der Klassentyp in der angezeigt wird rechts Handseite eines binären Operators. Zum Beispiel:

Foo f = 100;
int x = 10;
cout << x + f;

Dies funktioniert nur, wenn eine globale Operatorüberladung für vorhanden ist

Foo-Operator + (int x, const Foo& f);

Beachten Sie, dass die Überladung des globalen Operators nicht unbedingt a sein muss friend Funktion. Dies ist nur erforderlich, wenn Zugriff auf private Mitglieder benötigt wird Fooaber das ist nicht immer der Fall.

Egal, ob Foo hatte nur eine Memberfunktionsoperatorüberladung, wie:

class Foo
{
  ...
  Foo operator + (int x);
  ...
};

… dann könnten wir nur Ausdrücke haben, bei denen a Foo Instanz erscheint auf der links des Plusoperators.

  • +1 für die Unterscheidung zwischen Mitgliederfunktionen und Nichtmitgliedsfunktionen und nicht zwischen Mitglieder- und Freundfunktionen. Ich schätze, heute würden wir “globaler oder Namespace-Bereich” sagen.

    – Adrian McCarthy

    10. August 2016 um 18:46 Uhr

994490cookie-checkÜberladen von Operatoren: Member-Funktion vs. Nicht-Member-Funktion?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy