that Überladen von Mitgliedszugriffsoperatoren->,.*(C++)




double operator c (4)

->

Dies ist der einzige wirklich knifflige. Es muss eine nichtstatische Memberfunktion sein, die keine Argumente benötigt. Der Rückgabewert wird verwendet, um die Mitgliedersuche durchzuführen.

Wenn der Rückgabewert ein anderes Objekt des Klassentyps und kein Zeiger ist, wird die nachfolgende Membersuche auch von einer operator-> function gehandhabt. Dies wird als "Drilldown-Verhalten" bezeichnet. Die Sprache kettet die operator-> Aufrufe zusammen, bis die letzte einen Zeiger zurückgibt.

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

Dieses hier ist nur schwierig, da es nichts besonderes daran gibt. Die nicht überladene Version benötigt auf der linken Seite ein Objekt mit Zeiger auf den Klassentyp und auf der rechten Seite ein Objekt mit dem Zeiger auf den Elementtyp. Aber wenn Sie es überladen, können Sie beliebige Argumente nehmen und alles zurückgeben, was Sie wollen. Es muss nicht einmal ein nicht statisches Mitglied sein.

Mit anderen Worten, dieser ist nur ein normaler binärer Operator wie + , - und / . Siehe auch: Sind freie Betreiber -> * Überlasten böse?

.* und .

Diese können nicht überlastet werden. Es gibt bereits eine integrierte Bedeutung, wenn die linke Seite vom Klassentyp ist. Vielleicht würde es ein wenig Sinn machen, sie für einen Zeiger auf der linken Seite zu definieren, aber das Sprachdesignkomitee entschied, dass das verwirrender als nützlich wäre.

Überladen -> , ->* ,. , und .* kann nur Fälle ausfüllen, in denen ein Ausdruck undefiniert ist, er kann niemals die Bedeutung eines Ausdrucks ändern, der ohne Überladung gültig wäre.

Ich verstehe die meisten Überladungen von Operatoren mit Ausnahme der Zugriffsoperatoren für Mitglieder -> .* , ->* usw.

Insbesondere was wird an diese Operatorfunktionen übergeben und was sollte zurückgegeben werden?

Wie weiß der Operator (z. B. operator->(...) ), auf welches Element Bezug genommen wird? Kann es das wissen? Muss es das überhaupt wissen?

Gibt es schließlich noch Überlegungen, die berücksichtigt werden müssen? Wenn Sie zum Beispiel etwas wie operator[] überladen, benötigen Sie normalerweise sowohl eine const als auch eine nicht-const-Version. Erfordern Mitgliedszugriffsoperatoren const und non-const Versionen?


Der Operator -> weiß nicht, auf welches Element verwiesen wird, es stellt lediglich ein Objekt zur Verfügung, auf dem der tatsächliche Mitgliederzugriff ausgeführt werden kann.

Außerdem sehe ich keinen Grund, warum Sie nicht const und nicht-const Versionen bereitstellen können.


Wenn Sie den Operator -> () überladen (hier werden keine Argumente übergeben), ruft der Compiler -> 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 einkapselt. Der überladene Operator-> wird aufgerufen, tut was auch immer er tut (z. B. Sperren für Thread-Sicherheit), gibt den internen Zeiger zurück und dann ruft der Compiler -> für diesen internen Zeiger auf.

Wie für die Konstanz - es wurde in den Kommentaren und anderen Antworten beantwortet (Sie können und sollten beides bieten).


Betreiber -> ist etwas Besonderes.

"Es hat 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 welchen Zeiger der Dereferenzierungsoperator zeigt. " Bruce Eckel: Denken CPP Vol-One: Operator->

Die zusätzliche Funktionalität ist der Bequemlichkeit halber vorgesehen, sodass Sie nicht anrufen müssen

a->->func();

Sie können einfach tun:

a->func();

Das unterscheidet Operator -> von den anderen Operatorüberladungen.







c++-faq