Wie funktioniert der überladene -> Operator



  • Folgendes ist gegeben.

    template< class T >
    class A
    {
        public:
            T* operator->( void ){ return &Member; };
            T Member;   
    };
    
    class B
    {
        public:
            int Member2;
    };
    
    int main( void )
    {
        A< B > a;
        a->Member2 = 1; // der Rückgabewert von a-> ist ja eg B*. Warum
                        // funktioniert a->member2. Müsste es nicht a->->Member2 heißen? 
    }
    


  • Deine Logik ist richtig, aber der -> Operator stellt da etwas besonderes dar.
    Der ist genau für Solche Zwecke (Smaprpointers). Darum muss auch der Rückgabewert ein Zeiger oder ein Objekt, auf das -> angewendet werden kann sein.
    Das ist also ganz normales Verhalten des überladenen -> Operators.



  • uliws schrieb:

    ... Müsste es nicht a->->Member2 heißen? ...

    Zu drakons Beitrag wollte ich noch hinzufügen, dass solange der -> Operator einer Klasse keine Adresse (sprich keinen Zeiger-Typ, auf welchen der vordefinierte -> Operator angewendet werden kann) zurückgibt, solange wird rekursiv der -> Operator des zurückgegebenen Objekts aufgerufen, bis einer der ->Operatoren eine Adresse zurückgibt.

    In der Rekursion sind auch deine beiden ->-> versteckt. 🙂


  • Mod

    Genau genommen handelt es sich um keine Rekursion, sondern um eine Verkettung von Funktionaufrufen. Das Ergebnis des ersten Funktionsaufrufs ist Argument des zweiten, nicht umgekehrt. Zudem handelt es sich jeweils um die Operatoren unterschiedlicher Klassen (oder man spielt mit cv-basierter Überladung, jedenfalls darf das Ganze nicht zyklisch werden).

    foo.operator->().operator->() /* ... */ .operator->()->id
    

    Die "Magie" dieses Operators wirkt nur wenn auch die Operatorsyntax genutzt wird.



  • Ja, der Begriff rekursiv im Zusammenhang mit dem ->Operator ist schlicht falsch. Danke für den Hinweis. 🙂

    Man könnte sagen, "der Vorgang", des ständigen Aufrufens des ->Operators wird rekursiv durchgeführt. So, oder so ähnlichs stehts auch im Lippman.

    camper schrieb:

    ...Die "Magie" dieses Operators wirkt nur wenn auch die Operatorsyntax genutzt wird....

    😕 Wie jetzt? Welche Magie?



  • Hinzufügen schrieb:

    😕 Wie jetzt? Welche Magie?

    Na dass man sich das doppelte '->->' sparen kann: Wenn man nicht die Operatorsyntax verwendet, muss man es ja doch explizit verwenden: 'foo.operator ->()->…'



  • Konrad Rudolph schrieb:

    "... Wenn man nicht die Operatorsyntax verwendet, muss man es ja doch explizit verwenden: ..."

    Vielleicht ein kurzer Quellcode zur Demonstration des Unterschieds? Kann mir noch immer nichts darunter vorstellen, zumal es (meinem Verständnis nach!) keinen Unterschied machen sollte. 🙂



  • Konrad Rudolph hat ja ein Beispiel genannt. Steht ja da. Man muss nie ->-> hinereinander schreiben, auch wenn operator->()-> gemeint ist.


Anmelden zum Antworten