operator+ (nightly build)



  • hi,

    sollte ich eher

    zahl operator+(const zahl&)
    

    oder

    const zahl& operator+(const zahl&)
    

    nehmen?



  • Ersteres, bei Zweiterem würdest du ja eine Referenz auf ein lokales Objekt zurückgeben und noch dazu ein konstantes was die Verkettung von +-Operatoren verbieten würde.

    MfG SideWinder


  • Mod

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39474.html

    richtig richtig ist folglich keine der varianten, sondern:

    zahl operator+(const zahl&, const zahl&)
    

    als namespace funktion
    oder unter Umständen:

    zahl operator+(zahl, const zahl&)
    

    wenn du die gängige implementation mittels += durchführen willst.



  • SideWinder schrieb:

    eine Referenz auf ein lokales Objekt

    na und? ist denn nicht gewährleistet, dass es bis zum ende der aufrufenden anweisung existiert? war da nicht sowas?

    zurückgeben und noch dazu ein konstantes was die Verkettung von +-Operatoren verbieten würde.

    (btw, wie ging das nochmal? :D)

    na egal, dann ich nehm mal campers variante

    @camper:
    ich hab den thread jetzt nur kurz überflogen, aber geht es da nicht um funktionsparameter? ich gebe ja keine referenz auf einen parameter, sondern eine auf ein lokales objekt zurück.


  • Mod

    m3dus4 schrieb:

    @camper:
    ich hab den thread jetzt nur kurz überflogen, aber geht es da nicht um funktionsparameter? ich gebe ja keine referenz auf einen parameter, sondern eine auf ein lokales objekt zurück.

    ja, noch schlimmer!



  • ok, aber mein objekt kann jetzt ganz schön groß sein. wie verhindere ich die unnötige kopie 😕



  • Die Kopie ist nicht unnötig. Das Objekt, welches innerhalb der Funktion erstellt wird, ist auf dem Stack, d.h. es ist nach dem Funktionsaufruf weg.
    Wenn du Glück hast optimiert der Compiler diese Kopie des Objekts weg (-> Return value optimization).



  • Was meinst du eigentlich mit "nightly build" in der Überschrift?



  • m3dus4 schrieb:

    sollte ich eher

    zahl operator+(const zahl&)
    

    oder

    const zahl& operator+(const zahl&)
    

    nehmen?

    Weder noch, besser ist, du nimmst

    const zahl operator +(const zahl& lhs, const zahl& rhs)
    


  • @groovemaster: Wieso const? Nene, wenn schon außerhalb der Klasse dann bitte campers Variante 🙂

    MfG SideWinder



  • groovemaster schrieb:

    Weder noch, besser ist, du nimmst

    const zahl operator +(const zahl& lhs, const zahl& rhs)
    

    wieso keine member-methode?



  • m3dus4 schrieb:

    groovemaster schrieb:

    Weder noch, besser ist, du nimmst

    const zahl operator +(const zahl& lhs, const zahl& rhs)
    

    wieso keine member-methode?

    Weil eine solche keine Konvertierungen auf dem linken Operand zulässt. Eine solche ist aber im Sinne der Kommutativität der Addition.



  • SideWinder schrieb:

    [...]und noch dazu ein konstantes was die Verkettung von +-Operatoren verbieten würde.

    Das verstehe ich nicht. Die Verkettung hat hier doch nichts mit dem Return-Wert zu tun. D.h. auch wenn ich diesen als const deklariere, kann ich verschiedene Werte mit dem op+ verketten.
    Also sowas a la

    meine_klasse_mit_dem_const_op obj = o1 + o2 + o3 + ...;
    

    machen.

    Gruß Caipi



  • Hallo,
    für const spricht, dass ein Ausdruck wie (z1 + z2) = z3; zum Compile-Zeit-Fehler wird.



  • HumeSikkins schrieb:

    m3dus4 schrieb:

    groovemaster schrieb:

    Weder noch, besser ist, du nimmst

    const zahl operator +(const zahl& lhs, const zahl& rhs)
    

    wieso keine member-methode?

    Weil eine solche keine Konvertierungen auf dem linken Operand zulässt. Eine solche ist aber im Sinne der Kommutativität der Addition.

    häh? war das "keine" jetzt zuviel oder verstehe ich dich nicht?



  • nein, dass stimmt schon wie er's gesagt hat. wenn du den operator als Member - Funktion implementierst, kann der linke Operand nicht in deine Klasse konvertiert werden. Implementierst du sie global, geht es.



  • m3dus4 schrieb:

    HumeSikkins schrieb:

    m3dus4 schrieb:

    groovemaster schrieb:

    Weder noch, besser ist, du nimmst

    const zahl operator +(const zahl& lhs, const zahl& rhs)
    

    wieso keine member-methode?

    Weil eine solche keine Konvertierungen auf dem linken Operand zulässt. Eine solche ist aber im Sinne der Kommutativität der Addition.

    häh? war das "keine" jetzt zuviel oder verstehe ich dich nicht?

    Nein, aber der Satz ist trotzdem furchtbar mißverständlich.
    Also nochmal anders: angenommen Objekte deiner Klasse zahl lassen sich implizit aus ints erzeugen (zahl besitzt also einen Konvertierungs-Ctor). In diesem Fall kannst du dann sowas schreiben wie:

    zahl z = ...;
    zahl r = z + 42;
    

    Da Addition kommutativ ist (also a + b <-> b + a), solltest du genausogut auch

    zahl z = ...;
    zahl r = 42 + z;
    

    schreiben können.
    Dies setzt aber voraus, dass der linke Operand (42) zuvor in ein Objekt vom Typ zahl konvertiert wird. Konvertierungen auf dem linken Operand sind aber nur bei freien Funktionen möglich. Nicht aber bei Memberfunktionen. Aus diesem Grund solltest du den operator+ als freie Funktion implementieren.


  • Mod

    HumeSikkins schrieb:

    Hallo,
    für const spricht, dass ein Ausdruck wie (z1 + z2) = z3; zum Compile-Zeit-Fehler wird.

    und gegen const spricht, das auch die beste klase sich niemals gänzlich wie ein builtin typ verhalten wird (und im übrigen die meisten klassen ohnehin keine entsprechende vorlage in form von built-ins haben). ich habe noch niemanden gesehen, der mal soeben (z1+z2)=z3 schreibt - wer das tut, kriegt, was er verdient. und es hat ja bekanntlich keinen sinn, sich gegen machiaveli verteidigen zu wollen, der schreibt nähmlich noch ein const_cast dazu, un du hast nichts erreicht.
    ein non-const return kann zum beispiel dazu benutzt werden, move-konstruktoren zu implementieren, um so teure kopien, wie sie z.b. mit unbeschränkten zahlentypen auftreten können, zu vermeiden (RVO bzw. NRVO ist nunmal nicht in jeder situation möglich). es gibt ein menge legale und sinnvolle konstrukte, die ein non-const return voraussetzen, manche davon sind fast schon idiomatisch.



  • @camper
    ich habe ein const-return nicht empfohlen. Lediglich das gängige Pro-Argument aufgeführt.
    In meinen Augen gibt es vier potentielle Signaturen:

    1. T operator @ (const T&, const T&);
    2. const T operator @ (const T&, const T&);

    3. T operator @ (T, const T&);
    4. const T operator @ (T, const T&);

    Keine davon ist der eindeutige Sieger, da alle ihre Vor- und Nachteile haben. Ich bevorzuge 1. kann aber auch mit 2-4 leben.



  • camper schrieb:

    und gegen const spricht, das auch die beste klase sich niemals gänzlich wie ein builtin typ verhalten wird

    Wieso spricht das gegen const? Wenn überhaupt, dann spricht das nur nicht _für_ const.

    camper schrieb:

    und im übrigen die meisten klassen ohnehin keine entsprechende vorlage in form von built-ins haben

    Die meisten Klassen sind ja auch nicht als builtin ausgelegt. Trotzdem gibt es welche, die sich genau so anfühlen.

    camper schrieb:

    ich habe noch niemanden gesehen, der mal soeben (z1+z2)=z3 schreibt

    Da du ja schon einige Zeit hier im Forum aktiv bist, dürftest du mittlerweile mitbekommen haben, auf was für seltsame Ideen Leute so kommen. Deshalb zählt dieses Argument nicht.

    camper schrieb:

    und es hat ja bekanntlich keinen sinn, sich gegen machiaveli verteidigen zu wollen, der schreibt nähmlich noch ein const_cast dazu, un du hast nichts erreicht.

    Ein Stückchen mehr Sicherheit, wenn auch keine vollständige, würde ich nicht als nichts bezeichnen.

    camper schrieb:

    ein non-const return kann zum beispiel dazu benutzt werden, move-konstruktoren zu implementieren, um so teure kopien, wie sie z.b. mit unbeschränkten zahlentypen auftreten können, zu vermeiden (RVO bzw. NRVO ist nunmal nicht in jeder situation möglich).

    Mir ist zwar momentan nicht klar, was du mit "move-konstruktoren" meinst. Aber niemand sagt ja, dass du const Rückgaben verwenden _musst_. IdR verwende ich diese aber, da sie den aufgezeigten Nachteil nicht haben und gegenüber non-const Rückgaben auch keine anderen Nachteile aufweisen (afaik), sofern du nicht auf ein veränderbares Objekt angewiesen bist. Das ist ein bisschen so wie mit der Diskussion um explicit. Ist das momentan nun richtig spezifiziert? Oder sollte lieber jeder dtor explicit sein und dies nur bei Bedarf mit einem implicit Schlüsselwort ausgehebelt werden können?

    camper schrieb:

    es gibt ein menge legale und sinnvolle konstrukte, die ein non-const return voraussetzen, manche davon sind fast schon idiomatisch.

    Ach ja? Dann nenn doch mal ein paar. 10 dürften wohl für den Anfang reichen. Ich bin schon gespannt darauf, was neues kennenzulernen. Ich darf dich nochmal daran erinnern, wir reden über binäre Operatoren und du sagtest "legale" und "sinnvolle".


Anmelden zum Antworten