operator überladung(Freund und member-Funktion)
Was ist der Unterschied zwischen operator-überladung mithilfe der friend
Schlüsselwort und als member-Funktion innerhalb einer Klasse?
Auch, was ist der Unterschied in jedem Fall der unären operator überladen (d.h. als ein Freund, der vs als member-Funktion)?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Jacob ist richtig... ein
friend
Funktion deklariert, die innerhalb einer Klasse hat Zugriff auf diese Klasse, aber es ist nicht in der Klasse, und jeder andere Zugriff darauf hat.Für eine operator-überladung, die nicht Mitglied der Klasse (auch als einen free-Funktion, vielleicht ist es ein Freund, oder vielleicht auch nicht), die Argumente sind die gleichen wie die Operanden. Für eine, die ist ein Mitglied einer Klasse, der erste operand ist die "implizite argument" das wird
this
.Das implizite argument unterscheidet sich vom ersten argument, um eine Kostenlose Funktion in ein paar Möglichkeiten:
virtual
überlast gewählt werden, indem der dynamische Typ des ersten Operanden, das ist nicht möglich, mit Kostenlose Funktionen ohne zusätzlichen code.)Die situation ist die gleiche für unär, Binär oder n-Fach (im Fall von
operator()
).Mitglieder Privileg der mutation: die Betreiber, die änderung des ersten Operanden (z.B.
+=
,=
, Präfix++
) sollte durchgeführt werden als member-Funktionen, und sollte ausschließlich der Umsetzung der Eingeweide der alle überladungen. Postfix++
ist ein Bürger zweiter Klasse; implementiert ist es alsObj ret = *this; ++ this; return ret;
. Beachten Sie, dass dies manchmal reicht copy-Konstruktoren zu, die unter Umständen*this = initializer
.Herrschaft der Freiheit für Pendler: Nur Kommutative Operatoren (z.B.
/
) kostenlos sein sollte-Funktionen; alle anderen Operatoren (z.B. unäre nichts) sollten Mitglieder werden. Kommutative Operatoren inhärent eine Kopie des Objekts; Sie sind realisiert alsObj ret = lhs; ret @= rhs; return ret;
wo@
ist die Kommutative operator undlhs
undrhs
sind Links und rechts Argumente, beziehungsweise.Goldene Regel der C++ - Freundschaft: Vermeiden Freundschaft.
friend
belastet die Semantik der Konstruktion. Überlastung Folge: Überlastung ist einfach, wenn Sie Folgen Sie den oben genannten Regeln, dannfriend
harmlos ist.friend
ing boilerplate überlast-Definitionen erlaubt Ihnen, in derclass {
Klammern.Beachten Sie, dass einige Betreiber kann nicht frei sein, Funktionen:
=
,->
,[]
, und()
, weil der standard sagt ausdrücklich so in Abschnitt 13.5. Ich denke, das ist alles... ich dachte einfach&
und*
waren zu, aber ich war offensichtlich falsch. Sie sollte immer überladen werden als Mitglieder, obwohl, und nur nach sorgfältiger überlegung!friend
s) Freundschaft ist die Kupplung Beziehung und sollte vermieden werden (d.h. definierenoperatorX=
als Mitglied, und definierenoperatorX
im Hinblick aufoperatorX=
)class
block, die ich mag, und eigentlich Lockerung Zugang zu vermeiden Freundschaft mit binären op würde wahrscheinlich zerstörerisch sein—obwohl tatsächlich benötigen, Freundschaft wäre ein Grund, innezuhalten und nachzudenken.operator+=
als member-Funktion (die ist nicht erforderlich, aber geeignet scheint, das eine Art-Zuordnung) Sie können dann definierenX operator+( X lhs, X const & rhs ) { return lhs += rhs; }
ohne Lockerung Zugang. Auf der anderen Seite, der Vorteil (ich habe noch nie fand es ein Nachteil zu sein) zu definieren, die kostenlosen Funktionen (müssen Freunde sein) innerhalb der Klasse Klammern ist, dass Sie nicht nehmen Teil in dieser Art (das heißt, der compiler nicht zu, sollten Sie implizite Konvertierungen auf beiden Argumente zum Aufruf der Funktion)Der Unterschied ist, dass die friended-Funktion ist tatsächlich in der globalen scope, so dass Sie nicht brauchen, um eine Instanz der Klasse, die Zugriff darauf haben.
Einer member-Funktion erfordert, dass die linke hand Benutzer muss von diesem Typ.
Eine friend-Funktion kann erlauben implizite Typumwandlung auf die linke hand-operator.
So zum Beispiel, können sagen, wir schaffen eine BigInt-Klasse. Und erzeugen wir eine member-Funktion operator + rechts hand-operator "BigInt" enthält.
Nun können auch sagen BigInt hat einen Konstruktor, eine regelmäßige int. Dieser Konstruktor NICHT explicit (explicit-Schlüsselwort) und es nimmt einen parameter. Das bedeutet, dass C++ kann implitily konvertieren von int zu BigInt.
Wenn wir diese Dinge, die wir tun können, dieses:
BigInt foo( 5 );
BigInt-bar;
bar = foo + 5;
Aber wir KÖNNEN das NICHT machen:
BigInt foo( 5 )
BigInt-bar;
bar = 5 + foo;
Jedoch, wenn wir eine friend-Funktion statt einer member-Funktion dann beide funktionieren.
Einer member-Funktion erfordert, dass die linke hand Benutzer muss von diesem Typ. Eine friend-Funktion kann erlauben implizite Typumwandlung auf die linke hand-operator.
Member-Funktionen aufgerufen werden können, auf rvalues, in der Erwägung, dass die kostenlosen Funktionen akzeptieren Verweise auf nicht-const kann nicht aufgerufen werden, mit rvalues. Zum Beispiel
++function_returning_iterator_by_value()
nur kompiliert werden, wenn Sie implementierenoperator++
als Mitglied.