Operator überladen (Return const Referenz)



  • Hallo Zusammen,

    Ich beschätige mich gerade mit "Operatoren überladen", bin gerade beim Inkrement Operator. Die Klasse heisst "Counter". Im Buch ist sowas wie :

    const Counter& Counter::Operator++()
    {
        ++Val;
        return *this;
    }
    

    Ich habe viel im Internet gesucht, eine Erklärung konnte mich überzeugen.

    Ich gehe davon aus, es wird eine Referenz zurückgegeben um die Erzeugung eins temporären Objekts (Kopie) zu vermeiden.

    Was ich aber gar nicht verstehe ist, warum eine Konstante referenz zurücgegeben werden soll. Im Buch steht : " Wir verwenden eine konstante Ref, da der Wert nicht von der Funktion, die Counter verwendet, geändert werden soll". Welche Funktion ?

    Ich kenne dass man eine Konstante Ref als Parameter einer Funktion gibt, damit innerhalb der Funktion das Objekt nicht geändert werden soll... aber als Return verstehe ich es nicht.

    Ich hoffe jemand kann mir das genauer erklären.

    Ich habe auch gelesen, dass es vielleicht mit "operator chaining" zu tun hat, das verstehe ich aber ebenfalls nicht.

    Danke im Voraus.
    Gruss



  • Friend schrieb:

    Was ich aber gar nicht verstehe ist, warum eine Konstante referenz zurücgegeben werden soll. Im Buch steht : " Wir verwenden eine konstante Ref, da der Wert nicht von der Funktion, die Counter verwendet, geändert werden soll". Welche Funktion ?

    Naja, Du machst das ganze ja nicht zum Spass an der Freude. Irgendwo willst Du die Counter-Klasse doch verwenden! - und der Code soll dann nicht an Innereien von Counter rankommen.

    Edit: Kommt er auch mit 'ner normalen Ref nicht. Aber überleg Dir mal folgendes:

    Counter c;
    (c++)++

    Willst Du das erlauben? Bei ints ist sowas nicht möglich, also solltest Du es im Normalfall auch nicht erlauben.


  • Mod

    1. const ref an dieser Stelle ist Unfug.
    2. Der Autor gehört wahrscheinlich derselben Denkschule an, die früher generell für const-Rückgaben eingetreten ist. Das war schon immer wenig überzeugend (Funktionen sollten sich um sich selbst kümmern) und seit der Einführung von Movekonstruktion zum Glück verschwunden.
    3. Die Idee hier ist wahrscheinlich, dass Konstruktionen wie

    ++ ++i
    

    verhindert werden sollen, weil diese undefiniertes Verhalten zur Folge hätten, wenn der eingebaute ++-Operator zum Einsatz käme. Die Erklärung allerdings, warum bei der Übertragung eines Konzeptes (++) auf eine andere Domäne ausgerechnet UB mit zu übernehmen ist, wird allerdings nicht geliefert.


  • Mod

    SG1 schrieb:

    Bei ints ist sowas nicht möglich, also solltest Du es im Normalfall auch nicht erlauben.

    Er nutzt doch gar keine ints. Warum sollte deren Verhalten eine Rolle spielen? Was wird durch diese Beschränkung gewonnen?

    P.S. Dein Beispiel nutzt Postinkrement ist also sowieso prinzipiell ein anderer Fall (und mit Blick auf Movekonstruktion auch überholt).


  • Mod

    weil diese undefiniertes Verhalten zur Folge hätten, wenn der eingebaute ++-Operator zum Einsatz käme.

    Das war vor vielen langen Jahren mal der Fall (C++03 mangelte an sequence points), ist aber passé.


  • Mod

    Arcoth schrieb:

    weil diese undefiniertes Verhalten zur Folge hätten, wenn der eingebaute ++-Operator zum Einsatz käme.

    Das war vor vielen langen Jahren mal der Fall (C++03 mangelte an sequence points), ist aber passé.

    Quelle?


  • Mod

    camper schrieb:

    Arcoth schrieb:

    weil diese undefiniertes Verhalten zur Folge hätten, wenn der eingebaute ++-Operator zum Einsatz käme.

    Das war vor vielen langen Jahren mal der Fall (C++03 mangelte an sequence points), ist aber passé.

    Quelle?

    Nur um das klar zustellen: Wir reden hier von e.g. int i=0; ++++i; ? Oder hab' ich mich da irgendwie verlesen?



  • SG1 schrieb:

    (c++)++
    Willst Du das erlauben? Bei ints ist sowas nicht möglich, also solltest Du es im Normalfall auch nicht erlauben.

    Ich verstehe was du meinst. das heisst aber es wird nicht funktionieren wenn ich eine Funktion hätte " Func(Counter &x) " die x verändern soll wenn ich sie so aufrufe "Func(++i)", obwohl es sinnvoll wäre


  • Mod

    Nein, es wäre nicht sinnvoll. Es wäre auch nicht sinnvoll f(i = a) zu schreiben. Das ist einfach Bullshit. Schreib ++i; f(i); .



  • Arcoth schrieb:

    Das ist einfach Bullshit. Schreib ++i; f(i); .

    Mache ich :).

    Danke für eure Hilfe. bis zur nächsten Fragen


  • Mod

    Arcoth schrieb:

    Nein, es wäre nicht sinnvoll. Es wäre auch nicht sinnvoll f(i = a) zu schreiben. Das ist einfach Bullshit. Schreib ++i; f(i); .

    warum
    soll der Zuweisungsoperator also auch eine const-Referenz zurückgeben?



  • camper schrieb:

    Arcoth schrieb:

    Nein, es wäre nicht sinnvoll. Es wäre auch nicht sinnvoll f(i = a) zu schreiben. Das ist einfach Bullshit. Schreib ++i; f(i); .

    warum
    soll der Zuweisungsoperator also auch eine const-Referenz zurückgeben?

    void wäre toll.

    übrigens geht die welt nicht unter, wenn man seine eigenen ++-operatoren void zurückgeben läßt. ich mach's manchmal, wenn ihr nicht hinschaut.



  • @camper
    Es geht nicht darum dass man das nicht schreiben kann.
    Es geht darum dass man es nicht schreiben sollte.

    Klar sind das Stilfragen, und man kann da nicht richtig oder falsch sagen. (Naja, sagen kann man natürlich alles, man täte sich aber vermutlich schwer diesen Standpunkt auch zu verteidigen *g*)

    f(i = a) ist wohldefiniert, funktioniert, alles 1A.
    Ich würde trotzdem jeden Kollegen in dessen Code ich sowas sehe fragen ob er noch ganz dicht ist. Und darauf bestehen dass er es ändert.

    Kommt natürlich total drauf an was man gewohnt ist zu lesen. Nur... ich kann einfach keinen Wert darin erkennen sich anzulernen solche Konstrukte flüssig lesen zu können. Ausser natürlich man ist gezwungen in/mit Code zu arbeiten der so geschrieben ist. (Genau so wie ich es nicht für sinnvoll halte if (0 == Foo()) zu schreiben, nur weil es "Unfälle verhindert".)

    Was wiederrum nicht heisst dass ich deswegen als Return-Typ eines Zuweisungsoperators etwas anderes als T& verwenden würde, nur damit f(i = a) nicht mehr funktioniert. Weil ich es für wichtiger befinde sich an gut etablierte Standards zu halten, als zu versuchen irgendeine Dummheit zu verhindern. (Was dann auch oft genug nach hinten los geht.)


  • Mod

    volkard schrieb:

    void wäre toll.

    👍

    ich mach's manchmal, wenn ihr nicht hinschaut.

    Niemand missbilligt das.


Log in to reply