Operatoren überladen als member-Funktion oder nicht-Mitglied (friend -) Funktion?
Ich bin derzeit am erstellen einer utility-Klasse, die haben das überladen von Operatoren. Was sind die vor-und Nachteile, entweder Sie Mitglied oder nicht-Mitglied (friend
) Funktionen? Oder macht es überhaupt keinen Unterschied? Vielleicht gibt es eine best practice?
InformationsquelleAutor Seth | 2009-12-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Jeder Betreiber hat seine eigenen überlegungen. Zum Beispiel, die << operator (wenn Sie für die stream-Ausgabe, nicht bit-shifting) bekommt einen ostream als ersten parameter, also kann es nicht sein, ein Mitglied Ihrer Klasse. Wenn Sie die Umsetzung der Additions-operator, werden Sie wahrscheinlich wollen, profitieren von automatische Typ-Umwandlungen auf beiden Seiten, daher gehen Sie mit einem nicht-Mitglied so gut, etc...
Als für die Möglichkeit der Spezialisierung durch Vererbung, ein gemeinsames Muster ist die Umsetzung eines nicht-Mitglied-Betreiber im Sinne einer virtuellen member-Funktion (z.B. operator<< fordert eine virtuelle Funktion print() auf das Objekt übergeben wird).
InformationsquelleAutor On Freund
Dann würde ich mit "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices": wenn Sie es tun können, als nicht-member-Funktion, die es tun, als nicht-member-Funktion (die in dem gleichen Namensraum).
Einer der Gründe: es funktioniert besser mit impliziten Typ-Konvertierung. Ein Beispiel: Sie haben eine komplexe Klasse mit einem überladenen operator*. Wenn Sie möchten, schreiben 2.0 * aComplexNumber, müssen Sie den operator* eine nicht-member-Funktion.
Einem anderen Grund: geringere Kopplung. Nicht-member-Funktionen, die ein weniger eng gekoppelt als member-Funktionen. Dies ist fast immer eine gute Sache.
InformationsquelleAutor Tobias Langner
Wenn Sie planen, über die Umsetzung der streaming-Operatoren (<< und >>) dann werden Sie, für nicht-Mitglieder Methoden, weil Sie Ihre Objekt auf der linken Seite des operators.
Wenn Sie planen, umzusetzen ->, () oder [] Sie sind natürlich member-Methoden.
Für die anderen (Vergleichs-und mathematischen) Sie sollten überprüfen,Boost.Betreiber, es hilft wirklich.
Zum Beispiel, wenn Sie möchten, implementieren Sie die folgenden Operatoren:
Sie nur schreiben müssen:
Den 2
operator+
werden automatisch generiert, wie nicht-Mitgliedern, mit denen Sie profitieren von der automatischen Konvertierungen. Und Sie werden effizient durchgeführt werden, in der Bezeichnung desoperator+=
so schreiben Sie code, der nur einmal.InformationsquelleAutor Matthieu M.
Wenn Sie die op, dann die meisten wahrscheinlich, müssen Sie implementieren, op=. d.h. wenn Sie überladen von " + " - operator, dann sollten Sie implementieren +=.
Stellen Sie sicher, dass Sie zurückkehren const auf ein Objekt, wenn Sie tun, post-Inkrement-oder überlastung + - operator.
Also, wenn Sie überlast-operator + , dann setzen Sie es als nicht-member-operator und verwenden Sie den + = - operator drin. Für zB.
const A
? Ich habe gesehen das ein paar mal (gibt einen const-Wert) und konnte nie gefunden alle praktischen Vernunft...M., die uns daran hindert zu schreiben "(a+b)=c", die bereits nativ nicht mit primitiven Typen wie int.
Du hast vergessen die "const" für beide parameter-Deklarationen.
InformationsquelleAutor Jagannath
Für binäre Operatoren, die eine Einschränkung von member-Funktionen ist, dass das linke Objekt muss der Klasse geben. Dies kann begrenzen der operator symmetrisch ist.
Betrachten Sie eine einfache string-Klasse:
Wenn Sie implementieren operator+ als member-Funktion, während
str("1") + "2"
kompiliert wird,"1" + str("2")
wird nicht kompiliert.Aber wenn Sie implementieren operator+ als nicht-member-Funktion, dann diese beiden Aussagen legal.
InformationsquelleAutor R Samuel Klatchko
Es ist nichts, wie best practices, aber es hängt von der operator, den Sie sind überladen ..
E.g .
>> und << kann nicht überladen werden als member-Funktionen .
Angenommen, Sie möchten tun Sie dies : obj1 = 2 * obj2 dann gehen Sie für nicht-member-Funktion.
Für binärer operator überladen member-Funktion dauert nur 1 parameter (aufrufen Objekt ist impcliitly bestanden ) in der Erwägung, dass nicht-member-Funktion nimmt 2 Parameter .
danke, habe ich korrigiert.
<<
und>>
sicherlich können überladen werden als member-Funktionen, nur nicht, wenn Sie Sie verwenden möchten, als den stream-extraction/insertion Betreiber. Wenn Sie möchten, um Sie als shift-Operatoren, wie Dennis Ritchie soll, kein problem.InformationsquelleAutor Ashish