Rückgabewert des Zuweisungsopertors



  • Hi,
    Ich habe eine ganz simple Frage:
    Warum sollte / muss der Zuweisungsoperator eine Referenz zurückgeben?
    Eine Verkettung von Zuweisungen würde doch auch funktionieren, wenn ist statt
    einer Referenz eine Kopie zurückgebe.
    Also z.B. statt (Fall1):

    Complex& operator=(const Complex& rhs) {
       imag = rhs.imag;
       // usw...
       *this;
    }
    

    Das hier (Fall2):

    Complex operator=(const Complex& rhs) {
       imag = rhs.imag;
       // usw...
       *this;
    }
    

    Wenn ich jetzt Zuweisungen hätte, wie z.B.
    a = b = c;
    dann liefert der Teilausdruck (b=c) eben eine Kopie die dann in a kopiert wird.
    Wieso muss der Rückgabewert also eine Referenz sein??



  • bei einer referenz wird nicht erst eine lokale kopie des Complex objekts angelegt



  • Kann es sein, dass hier der einzige Grund eine Referenz und keine Kopie zurückzugeben die Effizienz ist?



  • interpreter schrieb:

    Kann es sein, dass hier der einzige Grund eine Referenz und keine Kopie zurückzugeben die Effizienz ist?

    Meistens sind Referenzen nur fuer Effizienz da.

    Du kannst fast alle Referenzen die du nicht polymorph verwendest ersetzen.



  • Wenn es nur um die Effizienz ginge, könnte man ja auch const T& zurückgeben. Das T& ist hier IMHO eher Konvention.



  • Ich schau auf Arbeit mal in Stroustrup nach, aber das lustige ist:

    Auch wenn die MSDN sagt

    "After the assignment, an assignment expression has the value of the left operand but is not an l-value"

    funktioniert folgendes trotzdem:

    (a=b)=c;
    

    (VC7, /Za) 🙄



  • Wenn du eine Referenz zurück gibst statt eriner konstanten Referenz ist das kein Wunder.



  • peterchen schrieb:

    Ich schau auf Arbeit mal in Stroustrup nach, aber das lustige ist:

    Auch wenn die MSDN sagt

    "After the assignment, an assignment expression has the value of the left operand but is not an l-value"

    funktioniert folgendes trotzdem:

    (a=b)=c;
    

    Die MSDN hat hier imo nur teilweise recht. Falls es sich bei a, b, c um eingebaute Typen handelt (z.B. int), dann ist das Ergebnis der Zuweisung ein lvalue (siehe 5.17/1). Falls es sich jedoch um UDTs handelt, dann ist das Ergebnis zwar modifizierbar (Aufruf einer non-const Memberfunktion), es lässt sich sogar der unäre Operator & drauf anwenden (immer ein gutes Zeichen für ein lvalue), es handelt sich aber nicht um ein lvalue (zumindest ist das meine Interpretation des Standards).

    Die Verwirrung rührt wahrscheinlich aus der häufig anzutreffenen, dennoch falschen Definition von lvalue, die da in etwa lautet: "lvalue ist das was auf der linken Seite einer Zuweisung stehen kann. rvalue alles andere". Diese Vereinfachung trifft auf C++ aber nicht zu.



  • @Helium:

    Sorry, hatte

    int a, b, c;
    

    vergessen 😉

    Falls es sich bei a, b, c um eingebaute Typen handelt (z.B. int), dann ist das Ergebnis der Zuweisung ein lvalue (siehe 5.17/1). Falls es sich jedoch um UDTs handelt, dann ist das Ergebnis zwar modifizierbar (Aufruf einer non-const Memberfunktion), es lässt sich sogar der unäre Operator & drauf anwenden (immer ein gutes Zeichen für ein lvalue), es handelt sich aber nicht um ein lvalue (zumindest ist das meine Interpretation des Standards).

    auweia...


Anmelden zum Antworten