Jacob ist korrekt ... eine friend
Funktion, die innerhalb einer Klasse deklariert wurde, hat Zugriff auf diese Klasse, aber sie ist nicht innerhalb der Klasse, und alle anderen haben Zugriff darauf.
Für eine Operatorüberladung, die kein Mitglied der Klasse ist (auch freie Funktion genannt, kann es ein Freund sein, oder vielleicht nicht), sind die Argumente die gleichen wie die Operanden. Für einen, der Mitglied einer Klasse ist, ist der erste Operand das "implizite Argument", das this
wird.
Die implizite Argument unterscheidet sich von dem ersten Argument zu einer freien Funktion in ein paar Möglichkeiten:
- Sein Typ ist Referenz-to-Klasse, während die freie Funktion jeder Art für das erste Argument erklären kann.
- Es beteiligt sich nicht an der impliziten Typkonvertierung. (Es wird nicht von einem Konvertierungskonstruktor temporär initialisiert.)
- Es nimmt an der virtuellen Override-Auflösung teil. (A
virtual
Überlast wird vom dynamischen Typ des ersten Operanden ausgewählt werden, die mit freien Funktionen ohne zusätzlichen Code nicht möglich ist.)
Die Situation ist das gleiche für unäre, binär oder n-ary (in der Fall von operator()
).
Mitglieder Privileg Mutation: Operatoren, die den ersten Operanden ändern (zB +=
, =
, Präfix ++
) als Member-Funktionen implementiert werden und sollten ausschließlich den Mut aller Überlastungen implementieren. Postfix ++
ist ein Bürger zweiter Klasse; Es ist implementiert als Obj ret = *this; ++ this; return ret;
. Beachten Sie, dass dies manchmal für Kopierkonstruktoren gilt, die *this = initializer
enthalten können.
Freiheitsregel für Pendler: Nur kommutative Operatoren (zB /
) sollten freie Funktionen haben; alle anderen Operatoren (z. B. unäre Dinge) sollten Mitglieder sein. Kommutative Operatoren machen von Natur aus eine Kopie des Objekts; Sie sind als Obj ret = lhs; ret @= rhs; return ret;
implementiert, wobei @
der kommutative Operator ist und lhs
und rhs
linksseitige und rechtsseitige Argumente sind.
Goldene Regel von C++ Freundschaft: vermeiden Freundschaft. friend
verschmutzt die Semantik eines Entwurfs. Überladung: Überladung ist einfach, wenn Sie die oben genannten Regeln befolgen, dann ist friend
harmlos. friend
Die Überladungsdefinitionen des Boilyplates ermöglichen es, sie in die class {
Zahnspange einzusetzen.
Beachten Sie, dass einige Betreiber nicht frei Funktionen können sein: =
, ->
, []
und ()
, weil der Standard sagt hierzu im Abschnitt 13.5. Ich denke, das ist alles ... Ich dachte, unary &
und *
waren auch, aber ich war anscheinend falsch. Sie sollten immer als Mitglieder jedoch überladen werden, und nur nach sorgfältiger Überlegung!
Warum können unäre Operatoren keine Freunde sein? – Vijay
Weil sie nicht nötig sind. Friend-Operatoren dürfen Ihnen ermöglichen, einen Klassentyp rechts von einem binären Operator anzugeben. Da unäre Operatoren keine rechte Seite haben, brauchen Sie sie nicht, um Freunde zu sein. – Stewart
@cpp: Sorry, ich habe mich an den Standard nicht erinnert. Vergiss es. – Potatoswatter