Wann gibt man eine konstante Referenz zurück?



  • Hallo Leute, habe eine Frage zu folgendem Code:

    const Counter& Counter::operator++()
    {
    ++itsVal;
    return *this;
    }

    Hier wurde der ++-Präfix-Operator überladen, wobei eine
    konstante Referenz auf das aktuelle Objekt (*this) zurückgegeben wird.
    Meine Frage ist jetzt, warum eine konstante Referenz zurückgegeben wird
    und nicht einfach eine normale bzw. eine nicht-konstante Referenz
    zurückgegeben wird.
    Was bewirkt man also damit, eine konstante Referenz zurückzugeben?
    Würde mich freuen, wenn mir das jemand erklären könnte.
    Danke schon mal an alle Tippfreudigen, die mir helfen möchten :)!



  • Man gibt eine konstante Referenz zurück, damit Code wie counter++ ++ nicht funktioniert. Denn normalerweise gibt der ++ -Postfixoperator den alten Wert zurück (insofern ist deine Implementierung "fehlerhaft"), ein erneutes Inkrementieren des alten Wertes ist sinnlos. Bei der Präfix-Version ist das aber durchaus möglich ( ++ ++counter ).

    Edit: ich sehe grade, ich habe mich verlesen, du implementierst ja die Präfix-Version. In dem Fall ist die konstante Referenz unintuitiv, die verwendet man bei der Postfix-Version.



  • Eine konstante Referenz gibst du dann zurück, wenn das Ergebnis nicht mehr direkt bearbeitbar sein soll, const eben:

    MyClass myobj;
    (myobj++) = 3; // wäre bei dir nicht möglich, da op++ ein const MyClass& liefert
    

    MfG SideWinder



  • Die Rückgabe einer Referenz auf konstante Objekte ist nicht unbedingt notwendig. Eine Faustregel bei Operatorüberladung heisst "Do as the ints do", soweit möglich. Das bedeutet in diesem Falle, der Präfix- operator++ sollte eine Referenz auf ein nicht-konstantes Objekt zurückgeben, da du sonst solche Dinge verhinderst, die mit int s möglich sind:

    Function(++myObject); // Function() nimmt Referenz
    

    Datax schrieb:

    eine nicht-konstante Referenz

    Sowas existiert in C++ nicht. Jede Referenz ist konstant.

    Was du meinst, ist das referenzierte Objekt, das über die Referenz verändert werden kann oder nicht. Ich ziehe es daher vor, von Referenz auf const oder Const-Referenz zu sprechen. Das nur so am Rande... 😉



  • Könntet ihr mir ein komplettes Code-Beispiel geben?
    Dann kann ich besser nachvollziehen, wie ihr das genau meint.
    Wäre super nett!



  • const vector<typ> & func(); (1)

    vector<typ> & func(); (2)

    Das da oben seien jetzt mal Methoden einer Klasse.

    (1)
    typ val = obj->func()[3]; // ok
    obj->func().push_back(wert) // fehler
    
    (2)
    typ val = obj->func()[3]; // ok
    obj->func().push_back(wert) // ok
    

    Auch wenn ich der Meinung bin,
    dass es in der Regel keine Gute Idee ist Referenzen aus Funktionen zurückzugeben,
    verdeutlicht dieses Beispiel doch sehr Gut den Unterschied in der Funktionalität.

    In beiden fällen gibst du eine Referenz zurück, doch mit dem const sagst du dazu,
    dass diese nicht verändert werden darf.

    Aber mal von diesr Funktionalität abgesehen gibst du den Compiler noch den Hinweis, das diese Referenz von außen auf keinen Fall geändert wird,
    was wohl auch für die ein oder andere Optimierung nützlich ist ( auch wenn ich davon keine Ahnung habe wie der Compiler so arbeitet).



  • Was macht denn genau die Funktion "push_back"?



  • Auf www.cplusplus.com nach vector suchen...



  • Alles klar, habe das jetzt verstanden mit der konstanten Referenz.
    Vielen Dank nochmal an alle, die mir geholfen haben :)!



  • Datax schrieb:

    const Counter& Counter::operator++()
    {
       ++itsVal;
       return *this;
    }
    

    Hier wurde der ++-Präfix-Operator überladen, wobei eine
    konstante Referenz auf das aktuelle Objekt (*this) zurückgegeben wird.
    Meine Frage ist jetzt, warum eine konstante Referenz zurückgegeben wird
    und nicht einfach eine normale bzw. eine nicht-konstante Referenz
    zurückgegeben wird.

    Keine Ahnung. Frag den Autor, was er sich dabei gedacht hat. Das entspricht jedenfalls nicht dem Verhalten von anderen Typen wie int .

    void haha(int&);
    void haha(Counter&);
    
    int main() {
      Counter c = ...;
      int     i = ...;
      ++++c; // funzt nicht
      ++++i; // funzt
      haha(++c); // funzt nicht
      haha(++i); // funzt
    }
    

    Datax schrieb:

    Was bewirkt man also damit, eine konstante Referenz zurückzugeben?

    Das übliche. Du kannst auf dem Ergebnis keine nicht-const Elementfunktionen aufrufen und auch nicht an Funktionen weitergeben, die eine nicht-const Referenz haben wollen.

    kk


Anmelden zum Antworten