Doppelter operator ->(), aber nur einmal hingeschrieben
-
Grüsse zusammen,
Kann mir einer erklären, wieso das geht? Oder liegt das an meinem Compiler, dass er nicht Standardkonform ist:
#include <iostream> class Outer { private: class Inner { public: Inner* operator ->() { return this; }; void test() { std::cout << "test" << std::endl; }; }; public: Inner operator ->() { return Inner(); } }; int main() { Outer outer; outer->test(); // Wieso muss ich hier nur einmal den operator ->() hinschreiben? return 0; }Grüssli
-
Der Compiler übernimmt das für dich. Durch das Hinschreiben des einen Operators ist bereits gesichert, dass solange ein Objekt bzw. eine Referenz zurückgegeben wird der -> Operator dieses Objekts aufgerufen wird, bis ein Zeigertyp zurückkommt auf den dann der vordefinierte ->Operator angewendet werden kann.
P.S.: Hat noch jemand Probleme mit dem Forum? Die Seite kann bei mir häufig nicht geladen werden.
-
Kritiker schrieb:
P.S.: Hat noch jemand Probleme mit dem Forum? Die Seite kann bei mir häufig nicht geladen werden.
Yep, bei mir genauso.
-
Ich werfe einfach noch mal eine Frage dazu (ich wollte auch mal einen Thread dazu aufmachen): Wieso funktioniert das eigentlich bei Iteratoren nicht?:
std::vector<Foo*>::iterator v; v->foo();
-
Badestrand schrieb:
Ich werfe einfach noch mal eine Frage dazu (ich wollte auch mal einen Thread dazu aufmachen): Wieso funktioniert das eigentlich bei Iteratoren nicht?:
std::vector<Foo*>::iterator v; v->foo();Weil bereits ein Zeiger zurückkommt, nehme ich an. Der opterator ->() vom Iterator in diesem Fall, liefert wohl ein Foo**.
@Kritiker,
Danke für die Antwort. Das ist mal wieder ein geile Feature von C++ zum Ausnutzen
Grüssli
-
Nehmen wir an, a sei vom Typ A, und foo ein Element des Typs A. Weiterhin habe A einen überladenen operator->. Dann passiert bei der Dereferenzierung über -> folgendes:
a->foo /* (1) entspricht */ decltype( A::operator-> ) tmp = a::operator->(); tmp->foo /* (2a) wenn decltype( A::operator-> ) ein Zeigertyp ist, wissen wir was passiert: (*tmp).foo */ /* (2b) wenn decltype( A::operator-> ) ein Objekttyp ist: GOTO (1) */Sprich, wenn das Ergebnis eines operator-> ein Typ ist, der selbst einen überladenen operator-> hat, wird dieser aufgerufen. Erst wenn das Ergebnis eines operator-> ein Zeigertyp ist, wird dereferenziert.
Bei Iteratoren klappt das nicht, weil das Ergebnis eines vector<int*>::operator-> vom Typ int** ist. Und ein int** ist, einmal dereferenziert, ein int*. Da ein int* kein Objekttyp mit überladenem operator-> ist, greift die o.a. Regel nicht.