Ich die meisten Betreiber Überlastung verstehen, mit Ausnahme der Mitgliedszugangsbetreiber ->
, .*
,->*
usw.
Was wird insbesondere an diese Operatorfunktionen übergeben und was sollte zurückgegeben werden?
Woher weiß die Bedienerfunktion (z. B. operator->(...)
), auf welches Mitglied verwiesen wird? Kann es wissen? Muss es überhaupt wissen?
Gibt es schließlich irgendwelche konstanten Überlegungen, die berücksichtigt werden müssen? Wenn Sie beispielsweise so etwas überladen operator[]
, benötigen Sie im Allgemeinen sowohl eine konstante als auch eine nicht konstante Version. Benötigen Mitgliederzugriffsoperatoren konstante und nicht konstante Versionen?
c++
operator-overloading
c++-faq
Bingo
quelle
quelle
const
und Nichtversionenconst
vonoperator->
sind nicht erforderlich , aber es kann nützlich sein, beide bereitzustellen.->*
und.*
. Tatsächlich werden sie nicht einmal erwähnt! Ich denke, sie sind zu selten, um in einer FAQ zu sein, aber ich würde diese Frage gerne aus der FAQ verlinken. Bitte schließen Sie dies nicht als Betrug der FAQ!Antworten:
->
Dies ist die einzige wirklich knifflige. Es muss eine nicht statische Elementfunktion sein und es werden keine Argumente akzeptiert. Der Rückgabewert wird verwendet, um die Mitgliedersuche durchzuführen.
Wenn der Rückgabewert ein anderes Objekt vom Klassentyp und kein Zeiger ist, wird die nachfolgende Mitgliedssuche auch von einer
operator->
Funktion verarbeitet. Dies wird als "Drilldown-Verhalten" bezeichnet. Die Sprache verkettet dieoperator->
Aufrufe, bis der letzte einen Zeiger zurückgibt.->*
Dieser ist nur insofern schwierig, als nichts Besonderes daran ist. Die nicht überladene Version erfordert ein Objekt des Zeigers auf den Klassentyp auf der linken Seite und ein Objekt des Zeigers auf den Elementtyp auf der rechten Seite. Wenn Sie es jedoch überladen, können Sie beliebige Argumente verwenden und alles zurückgeben, was Sie möchten. Es muss nicht einmal ein nicht statisches Mitglied sein.
Mit anderen Worten, dies ist ein nur ein normaler Binäroperators wie
+
,-
und/
. Siehe auch: Sind freie Operatoren -> * Überladungen böse?.*
und.
Diese können nicht überladen werden. Es gibt bereits eine eingebaute Bedeutung, wenn die linke Seite vom Klassentyp ist. Vielleicht wäre es ein wenig sinnvoll, sie für einen Zeiger auf der linken Seite definieren zu können, aber das Komitee für Sprachdesign entschied, dass dies eher verwirrend als nützlich wäre.
Überlastung
->
,->*
,.
, und.*
in Fällen , nur füllen kann , wo ein Ausdruck undefiniert sein würde, kann es nie die Bedeutung eines Ausdrucks ändern, ohne eine Überlastung gültig wäre.quelle
new
Operator überladen , obwohl er auch dann gültig ist, wenn er nicht überladen ist.new
ist immer überladen oder Überladungsregeln gelten nicht wirklich für ihn (13.5 / 5: Die Zuordnungs- und Freigabefunktionen Operator neu, Operator neu [], Operator löschen und Operator löschen [] werden in 3.7 vollständig beschrieben 0,4. die Attribute und in dem Rest dieses Subklausel gefunden Einschränkungen gelten nicht für sie , sofern nicht ausdrücklich in 3.7.4 angegeben.) Aber einstellige Überlastung&
oder binär&&
,||
oder,
, oder das Hinzufügen von Überlastungenoperator=
oder Überlastung einfach alles für ein unscoped Aufzählungstyp, kann die Bedeutung eines Ausdrucks ändern. Klarstellung der Aussage, danke!Operator -> ist etwas Besonderes.
"Es gibt zusätzliche atypische Einschränkungen: Es muss ein Objekt (oder einen Verweis auf ein Objekt) zurückgeben, das auch einen Zeiger-Dereferenzierungsoperator hat, oder es muss einen Zeiger zurückgeben, mit dem ausgewählt werden kann, auf was der Pfeil des Zeiger-Dereferenzierungsoperators zeigt. "" Bruce Eckel: Denken CPP Vol-One: Operator->
Die zusätzliche Funktionalität wird zur Vereinfachung bereitgestellt, sodass Sie nicht anrufen müssen
Sie können einfach tun:
Das unterscheidet den Bediener -> von den anderen Bedienerüberlastungen.
quelle
Sie können den Mitgliederzugriff nicht überladen
.
(dh den zweiten Teil dessen, was->
funktioniert). Sie können jedoch die unäre Dereferenzierung überladen Operator*
(dh der erste Teil von dem, was der->
Fall ist).Der C ++ -
->
Operator ist im Grunde die Vereinigung von zwei Schritten, und dies ist klar, wenn Sie denken, dass diesx->y
äquivalent zu ist(*x).y
. Mit C ++ können Sie anpassen, was mit dem(*x)
Teil geschehenx
soll, wenn es sich um eine Instanz Ihrer Klasse handelt.Die Semantik für das
->
Überladen ist etwas seltsam, da Sie in C ++ entweder einen regulären Zeiger zurückgeben können (der zum Auffinden des spitzen Objekts verwendet wird) oder eine Instanz einer anderen Klasse zurückgeben können, wenn diese Klasse auch einen->
Operator bereitstellt . In diesem zweiten Fall wird die Suche nach dem dereferenzierten Objekt von dieser neuen Instanz aus fortgesetzt.quelle
->*
, da es der Form von(*x).*
? Entspricht .Das
->
Bediener weiß nicht, auf welches Mitglied verwiesen wird, sondern stellt lediglich ein Objekt bereit, für das der eigentliche Elementzugriff ausgeführt werden soll.Außerdem sehe ich keinen Grund, warum Sie keine konstanten und nicht konstanten Versionen bereitstellen können.
quelle
Wenn Sie den Operator -> () überladen (hier werden keine Argumente übergeben), ruft der Compiler tatsächlich -> rekursiv auf, bis er einen tatsächlichen Zeiger auf einen Typ zurückgibt. Es verwendet dann das richtige Mitglied / die richtige Methode.
Dies ist beispielsweise nützlich, um eine intelligente Zeigerklasse zu erstellen, die den tatsächlichen Zeiger kapselt. Der überladene Operator-> wird aufgerufen, macht alles, was er tut (z. B. Sperren für die Thread-Sicherheit), gibt den internen Zeiger zurück und der Compiler ruft dann -> für diesen internen Zeiger auf.
Die Konstanz wurde in den Kommentaren und anderen Antworten beantwortet (Sie können und sollten beides angeben).
quelle