Generelle Verständnisfrage zum this-Zeiger



  • Ich verstehe this-Zeiger als return-Wert einer Methode nicht. Warum sollte man die Adresse des eigenen Objekts als return Wert zurück geben? Was nimmt der this-Zeiger sonst für Informationen auf? Einen Ausdruck als return-Wert verstehe ich, aber mit Referenzen/Zeigern ist das sone Sache. Kann mir einer helfen?

    edit:
    Falls Beispiel benötigt, werde ich eines Suchen.



  • Man kann damit furchbar viele Sachen in eine Zeile schreiben.

    #include <iostream>
    using namespace std;
    
    struct Foo{
    	Foo* f1(){
    		cout<<"f1\n";
      return this;
      }
    	Foo* f2(){
    		cout<<"f2\n";
      return this;
      }
    };
    int main(){
    	delete (new Foo)->f1()->f2()->f1();//helau!
    }
    


  • volkard schrieb:

    Foo* Foo::f1(){
      tuwas1();
      return this;
    }
    Foo* Foo::f2(){
      tuwas2();
      return this;
    }
    ...
    Foo *f=new Foo;
    f->f1()->f2();//helau!
    

    Danke. In meinem Buch wird der this-Zeiger allerdings auch dereferenziert (*this). Welche Bedeutung hat das?



  • *this, um eine Referenz zurückzugeben.

    ...
    return *this
    ...
    f.f1().f2()
    

    Vor allem gut ist das zum Beispiel für

    cout<<"hallo"<<"welt"<<'\n';
    

    Das ist ja

    cout.operator<<("hallo").operator<<("welt").operator<<('\n');
    


  • volkard schrieb:

    Vor allem gut ist das zum Beispiel für [...]

    Oder auch oft für den Zuweisungsoperator (oder arithmetische Zuweisungsoperatoren wie += ), die eine Referenz auf das Objekt zurückgeben.

    Manche Leute benutzen this-> auch, um Membervariablen zu kennzeichnen oder von gleichnamigen Parametern abzugrenzen, ich persönlich finde das allerdings nicht so schön und nehme stattdessen meistens ein Präfix m_ oder My .

    Grundsätzlich braucht man this halt, wenn man innerhalb der Memberfunktionen einer Klasse auf das Objekt an sich bzw. dessen Adresse zugreifen möchte.



  • Nexus schrieb:

    volkard schrieb:

    Vor allem gut ist das zum Beispiel für [...]

    Oder auch oft für den Zuweisungsoperator (oder arithmetische Zuweisungsoperatoren wie += ), die eine Referenz auf das Objekt zurückgeben.

    Manche Leute benutzen this-> auch, um Membervariablen zu kennzeichnen oder von gleichnamigen Parametern abzugrenzen, ich persönlich finde das allerdings nicht so schön und nehme stattdessen meistens ein Präfix m_ oder My .

    Grundsätzlich braucht man this halt, wenn man innerhalb der Memberfunktionen einer Klasse auf das Objekt an sich bzw. dessen Adresse zugreifen möchte.

    Ok, das verstehe ich jetzt, aber noch was anderes:

    Angenommen ich habe diesen CODE-Abschnitt hier:

    class Foo
    {
    private:
            long zaehler, nenner;
    
    Foo& operator+=(const Foo& a)
    {
         zaehler = a.zaehler * nenner + zaehler * a.nenner;
         nenner *= a.nenner;
         return *this;
    }
    };
    
    int main()
    {
       Foo obj1, obj2;
       obj1 += obj2;
    }
    

    Dann ist der operator += für das Objekt obj1 überladen? Und wenn ja, wie kann das sein? Ich mein' die Methode gibt doch nur die Referenz zum Objekt zurück (und Referenz zum Objekt zurückgeben stelle ich mir so vor, dass die Adresse des Objektes zurückgegeben wird) aber doch nicht den Operator??
    😕

    Öhm, ich habe ne Theorie: Das aktuelle Objekt obj1 wird verändert, also wirkt sich die Änderung einfach direkt auf den linken Operanden aus... Oder?

    obj1 += obj2;
    

    *Woher weiß aber this denn, dass vorher in der Operatorfunktion etwas definiert wurde? Ich kenne das ja so, dass eine Routine Daten verarbeitet und dieselben anschließend per return zurückgibt. Aber hier werden Daten verarbeitet und anschließend wir eine Referenz auf das aktuelle Objekt zurückgegeben. *Eine Verbindung zwischen this und den vorherigen Anweisungen mit zaehler, a und nenner fehlt mir. Natürlich kann es auch sein, dass zaehler und nenner einfach nur geändert werden sollen, sobald

    obj1 += obj2;
    

    aufgerufen wird und damit basta. Wozu dann aber noch die Anweisung return *this; ? Der einzige Fall, den ich verstehen würde, ist der, dass das aktuelle Objekt verändert wird. Denn dann hat es sinn, es dann auch zurückzugeben. In dem Fall müsste die Operatorfunktion IMPLIZIT this-Zeiger auf zaehler und nenner setzen, stimmt's?
    Bin ich zu doof dafür?



  • In deinem Beispiel macht es nicht viel Sinn, allerdings will man ev. das hier machen:

    int main()
    {
       Foo obj1, obj2,obj3;
    
      (obj1 += obj2) += obj3;
    }
    

    Nicht sonderlich schön usw., allerdings durchaus möglich.

    Dann ist der operator += für das Objekt obj1 überladen?

    Nicht überladen. Sondern überhaupt deklariert und definiert.

    Du solltest dir Operatoren als ganz normale Funktionen mit halt ein wenig Syntax Sugar vorstellen.

    obj1 += obj2;
    

    bedeutet nichts anderes, als:

    obj1.operator += ( obj2 );
    


  • skullyan schrieb:

    Dann ist der operator += für das Objekt obj1 überladen?

    Nein, er ist für die Klasse Foo überladen. Für einzelne Objekte kannm an nichts überladen. In dem Aufruf den du oben gezeigt hast wird die Rückgabe des op+= nicht benutzt.

    Öhm, ich habe ne Theorie: Das aktuelle Objekt obj1 wird verändert, also wirkt sich die Änderung einfach direkt auf den linken Operanden aus... Oder?

    so stehts zumindest in der Definition der Operatorüberladung, ja.

    *Woher weiß aber this denn, dass vorher in der Operatorfunktion etwas definiert wurde?

    Garnicht. braucht es auch nicht zu wissen. Der operator += ist eine Methode wie jede normale Methode auch. sie mach was mit einem Objekt und gibt danach als Rückgabewert eine Referenz auf das grade geänderte Objekt zurück.

    Ich kenne das ja so, dass eine Routine Daten verarbeitet und dieselben anschließend per return zurückgibt.

    Nicht wirklich. Eine Routine kann alles mögliche zurückgeben. Zum Beispiel einen neuen Wert (z.B. das Ergebnis einer Addition), eine Kopie eines vorhandenen Wertes (z.B. bei Gettern), eine Referenz auf irgendeinen anderen Wert, oder eben wie bei return *this; eine Referenz auf eines der geänderten Objekte.

    Aber hier werden Daten verarbeitet und anschließend wir eine Referenz auf das aktuelle Objekt zurückgegeben. *Eine Verbindung zwischen this und den vorherigen Anweisungen mit zaehler, a und nenner fehlt mir.

    *this ist das Objekt auf das sich die Änderungen bezogen haben. Die Member von *this sind gerade geändert worden. *this ist immer das Objekt, das in der MEthode verarbeitet wird, bzw. für das die Methode aufgerufen wird. Bei obj1 += obj2 ist *this == obj1

    Natürlich kann es auch sein, dass zaehler und nenner einfach nur geändert werden sollen, sobald

    obj1 += obj2;
    

    aufgerufen wird und damit basta. Wozu dann aber noch die Anweisung return *this; ? Der einzige Fall, den ich verstehen würde, ist der, dass das aktuelle Objekt verändert wird. Denn dann hat es sinn, es dann auch zurückzugeben. In dem Fall müsste die Operatorfunktion IMPLIZIT this-Zeiger auf zaehler und nenner setzen, stimmt's?

    Genau das ist der Sinn des this-Zeigers. Sollte eigentlich im Beginners' Tutorial deiner Wahl stehen.



  • pumuckl schrieb:

    skullyan schrieb:

    Dann ist der operator += für das Objekt obj1 überladen?

    Nein, er ist für die Klasse Foo überladen. Für einzelne Objekte kannm an nichts überladen. In dem Aufruf den du oben gezeigt hast wird die Rückgabe des op+= nicht benutzt.

    Öhm, ich habe ne Theorie: Das aktuelle Objekt obj1 wird verändert, also wirkt sich die Änderung einfach direkt auf den linken Operanden aus... Oder?

    so stehts zumindest in der Definition der Operatorüberladung, ja.

    *Woher weiß aber this denn, dass vorher in der Operatorfunktion etwas definiert wurde?

    Garnicht. braucht es auch nicht zu wissen. Der operator += ist eine Methode wie jede normale Methode auch. sie mach was mit einem Objekt und gibt danach als Rückgabewert eine Referenz auf das grade geänderte Objekt zurück.

    Ich kenne das ja so, dass eine Routine Daten verarbeitet und dieselben anschließend per return zurückgibt.

    Nicht wirklich. Eine Routine kann alles mögliche zurückgeben. Zum Beispiel einen neuen Wert (z.B. das Ergebnis einer Addition), eine Kopie eines vorhandenen Wertes (z.B. bei Gettern), eine Referenz auf irgendeinen anderen Wert, oder eben wie bei return *this; eine Referenz auf eines der geänderten Objekte.

    Aber hier werden Daten verarbeitet und anschließend wir eine Referenz auf das aktuelle Objekt zurückgegeben. *Eine Verbindung zwischen this und den vorherigen Anweisungen mit zaehler, a und nenner fehlt mir.

    *this ist das Objekt auf das sich die Änderungen bezogen haben. Die Member von *this sind gerade geändert worden. *this ist immer das Objekt, das in der MEthode verarbeitet wird, bzw. für das die Methode aufgerufen wird. Bei obj1 += obj2 ist *this == obj1

    Natürlich kann es auch sein, dass zaehler und nenner einfach nur geändert werden sollen, sobald

    obj1 += obj2;
    

    aufgerufen wird und damit basta. Wozu dann aber noch die Anweisung return *this; ? Der einzige Fall, den ich verstehen würde, ist der, dass das aktuelle Objekt verändert wird. Denn dann hat es sinn, es dann auch zurückzugeben. In dem Fall müsste die Operatorfunktion IMPLIZIT this-Zeiger auf zaehler und nenner setzen, stimmt's?

    Genau das ist der Sinn des this-Zeigers. Sollte eigentlich im Beginners' Tutorial deiner Wahl stehen.

    Ok, habs kapiert, danke!
    🙂


Anmelden zum Antworten