Value by reference



  • hallo,

    ich habe eine klasse mit vielen set-methoden und hab mir überlegt überall die parameter als referenz zu machen. gibt es was gegen:

    set_timeout( const unsigned int &timeout )
    

    einzuwenden? warum macht man nicht überall diese referenzen hin ?



  • Sinnlos bei primitiven Datentypen



  • warum? wenn er es als Referenz übergeben will?



  • Die Größe der Variable die kopiert wird und die der Referenz ist identisch. Daher kein Vorteil.



  • Basingstoke schrieb:

    warum? wenn er es als Referenz übergeben will?

    Da steht ein const davor => sinnlos



  • Fellhuhn schrieb:

    Die Größe der Variable die kopiert wird und die der Referenz ist identisch. Daher kein Vorteil.

    Wer sagt das? Woher willst du wissen, das der Compiler Referenzen als Pointer implementiert? Ist das nicht eher Compiler-abhängig? Und somit eine Pauschalaussage nicht wirklich richtig?



  • Unabhängig davon wie es unter der Haube aussieht, wird in eigentlich jeden aktuellen Quellen (auch grade von den C++ Gurus ;p) das man primitive Datentypen "By Value" und Objekte "by const Referenz" übergeben sollte. Daher würde ich mich erst einmal daran halten, auch wenn mir Bewusst ist das sich Regeln mit der Zeit ändern können.

    cu André



  • Sinner schrieb:

    Basingstoke schrieb:

    warum? wenn er es als Referenz übergeben will?

    Da steht ein const davor => sinnlos

    😕 ähh nö - wieso ?
    Der Unterschied zwischen einer const- und einer non-const-Referenz sollte doch wohl auf der Hand liegen, oder ?
    Selbst bei einem Call by Value kann ein const eine "Programmierhilfe" sein, wenn man sicherstellen will, dass man bei der Implementation nur const-Funktionen auf die Kopie anwenden will ... (MUSS man nicht, mache ich auch eher selten, ist aber nicht per definitionem sinnlos - spätestens bei templates ist das gar nicht so dumm)

    Gruß,

    Simon2.



  • er meint sinnlos, weil man es dann nicht wirklich als Referenz verwenden will, sondern nur den Geschwindigkeitsvorteil haben will.

    war wohl auf die ersten beiden Antworten bezogen



  • mhm schrieb:

    er meint sinnlos, weil man es dann nicht wirklich als Referenz verwenden will, sondern nur den Geschwindigkeitsvorteil haben will.

    war wohl auf die ersten beiden Antworten bezogen

    richtig

    Und so Aussagen "woher wollt ihr wissen, dass Referenzen als Pointer implementier sind?" haben auch maximal theoretischen Wert. Jeder mir bekannte Compiler implementiert Referenzen durch Pointer (auch irgendwie naheliegend), also macht es keinen Sinn über irgendwelche theoretischen Möglichkeiten zu reden.

    Ergo: primitive Datentypen => Value
    sonst => Referenz (wenns geht)



  • Konstante Referenzen kann man auch verändern, dazu ist ja const_cast da. Also schon ein Unterschied. 😉



  • Sinner schrieb:

    mhm schrieb:

    er meint sinnlos, weil man es dann nicht wirklich als Referenz verwenden will, ...

    richtig...

    Aha !
    Merke: Wenn man schreibt, was man meint, wird man weniger mißverstanden.

    Gruß,

    Simon2.



  • Fellhuhn schrieb:

    Konstante Referenzen kann man auch verändern, dazu ist ja const_cast da. Also schon ein Unterschied. 😉

    Nein, dafür ist const_cast eben nicht da. Konstante Werte sollte man niemals ändern. const_cast hat vor allem die Bewandnis das man allte Schnittstellen (z.B. externe) verwenden kann wo - obwohl keine Änderung erfolgt - keine const-Deklaration statt gefunden hat.

    cu André



  • asc schrieb:

    ... Konstante Werte sollte man niemals ändern....

    Richtig. Aber man kann. Und daher ist es ein Unterschied. Habe ja nicht gesagt das man es soll. 😉



  • Fellhuhn schrieb:

    ...Aber man kann....

    ... und springt damit über die Grenzen des Standards hinaus in den weiten Raum "undefiniertes Verhalten".
    Mit Deiner Formulierung suggerierst Du aber Anderes.

    Genauso könnte ich sagen: "Pi kann man als 2 definieren".
    Da gilt auch: "Ja, man kann"
    .. aber eben auch: "Dann sollte man sich aber nicht darauf verlassen, dass alles Andere noch funktioniert/gilt"

    Gruß,

    Simon2.



  • Undefiniert? Das ist der Sinn von const_cast.



  • void f(int const& fi);
    
    int main() {
       const int i = 3;
       f(i);
       cout << i;
       return 0;
    }
    
    void f(int const& fi) {
       int& i = const_cast<int>(fi);
       i++;
    }
    

    undefiniert eben.

    Du hast geschrieben (in einer allgemeinen Diskussion über Schnittstellen):

    Fellhuhn schrieb:

    Konstante Referenzen kann man auch verändern, dazu ist ja const_cast da....

    ... und das stimmt einfach nicht.
    Stattdessen hat asc es gut auf den Punkt gebracht:

    asc schrieb:

    ...
    Nein, dafür ist const_cast eben nicht da. Konstante Werte sollte man niemals ändern. const_cast hat vor allem die Bewandnis das man allte Schnittstellen (z.B. externe) verwenden kann wo - obwohl keine Änderung erfolgt - keine const-Deklaration statt gefunden hat....

    ... und dieses "sollte man niemals ändern" ist nicht ein netter Design-Tipp unter Freunden, sondern eine andere Formulierung von "Ergebnis ist undefiniert".
    Manchmal ist "undefiniert" das geringere Übel und da ist const_cast das Mittel der Wahl, aber es ist nicht das generelle Mittel, um "... konstante Referenzen zu ändern ...".

    Gruß,

    Simon2.



  • Das ist kein Stück undefiniert. "Definierter" geht es gar nicht. Es mag in deinem Programm zu komischen Ergebnissen führen, die aber komplett dem Standard entsprechen.
    Das es absolut schlechter Stil ist, ist ganz was anderes. Aber zu behauptet eine konstante Referenz auf einen primitiven Datentyp und ein call by Value wäre identisch, ist absolut falsch.



  • Fellhuhn schrieb:

    Das ist kein Stück undefiniert.

    Doch, das ist undefiniert. 'const_cast' darf lt. Standard nur auf Werte angewandt werden, die nicht 'const' angelegt worden sind (ich bin zu faul, den genauen Wortlaut herauszusuchen). Wenn man 'i' also non-const deklariert hätte, wäre der Code wohldefiniert, sonst nicht. (Zumindest ist es bei Zeigern so, ob das auch für Referenzen gilt, weiß ich nicht.)



  • Fellhuhn schrieb:

    Das ist kein Stück undefiniert. "Definierter" geht es gar nicht.

    Nein. Es ist undefiniert. Das "entconsten" einer konstanten Variable (Beachte: Das Ursprungsobjekt ist konstant!) führt zu undefiniertem Verhalten. Punkt.

    Was Du wahrscheinlich meinst ist:

    void f(int const& fi);
    
    int main() {
       int i = 3; // KEIN const
       f(i);
       cout << i;
       return 0;
    }
    
    void f(int const& fi) {
       int& i = const_cast<int>(fi);
       i++;
    }
    

    BTW: Beim cast fehlt glaube ich ein & in den <>.


Anmelden zum Antworten