Warum ist es sinnvoll eine Rückgabetypen einer Elementfuktion mit const datentyp referenz (&) zu bestimmen



  • Hallo,
    Ich Habe in Meinen Buch etwas über Klassen gelesen. An einer Stelle wird der Rückgabetyp einer Elemtarfunktion einer Klasse mit const klassenname & beschrieben.
    Nun frage ich mich, warum macht es sinn einen Rückgabetypen einer Funktion mit einer Refernez zu gestallten. Mir ist zwar bewusst was eine Referenze macht, aber trotzdem verstehe ich nicht wieso man das so machen soll.
    Immerhin kann man den Rückgabetypen nach der return Anweisung sowieso nicht mehr verändern, also macht es doch keinen unterscheid ob man nun den Rüchgabewert per Wert oder per Refernez macht.
    Außerdem verstehe ich nicht wieso man noch das const zusätzlich bracht.



  • Wenn der Compiler die Rueckgabe nicht wegoptimieren kann, wird bei einer Call by Value Rueckgabe die Variable kopiert.

    Je nachdem wie "schwer" die Variable ist kann das ziemlich ineffizient und teuer sein. Wenn Du schon C++ programmierst dann solltest Du darauf achten den Code nicht unnoetigerweise "langsamer" zu machen.

    Manchmal will eine Funktion e.g. einfach nur auf einen Wert zugreifen (GET) und es macht dann absolut keinen Sinn eine Variable zu kopieren, deswegen returned man die Variable e.g. als const referenz, denn dann ist absolut kein Kopiervorgang notwendig und der "User" deiner Funktion kann nicht ausversehen die Variable veraendern.

    Wenn naemlich eine Referenz returned wird die nicht Const ist kann der Konsument deiner "Get" Funktion ansonsten die Variable (die hoechstwahrscheinlich private deklariert ist) "unter deinem Hintern" einfach aendern.


  • Mod

    win8789 schrieb:

    Immerhin kann man den Rückgabetypen nach der return Anweisung sowieso nicht mehr verändern,

    Doch!

    Was dann wohl deine Frage beantworten dürfte.

    Hier noch ein Beispiel, falls du es nicht glaubst:

    #include <iostream>
    
    struct Foo
    {
      int i = 0;
      int & get_i() { return i;}
    };
    
    int main()
    {
      Foo foo;
      std::cout << foo.i << '\n';  // 0
      foo.get_i() = 3;
      std::cout << foo.i << '\n';  // 3
    }
    


  • Wenn du eine const Referenz als Rückgabewert hast wird der Wert nicht kopiert und der Benutzer deiner Funktion kann dann irgendwas mit der Referenz machen. In vielen Fällen kann der aber mit der const Referenz alles machen was er möchte und braucht gar keine Kopie. Wenn er doch eine Kopie braucht, erstellt er eben ein (statt immer zu Kopieren wie es bei Rückgabewerten ohne Referenz wäre). Das zusätzliche const sorgt dafür, dass man den originalen Wert der in dem Objekt nicht verändern kann. Ein typisches Anwendungsbeispiel:

    // Irgendeine Memberfunktion
    const std::string& Someclass::getInfo()
    {
        return info;
    }
    
    int main()
    {
        Someclass obj;
        std::string bla = obj.getInfo(); // Kopie vom internen String!
        bla += "stuff";                  // Kopie wird bearbeitet
        std::cout << bla << endl;
    
        std::cout << obj.getInfo() << endl;  // Keine Kopie!
    }
    


  • int main() {
      vector<int> v(1, 1);
      int const& i = v[0]; // const-referenz
      cout << i << '\n';   // Ausgabe: 1
      v[0] = 2;
      cout << i << '\n';   // Ausgabe: 2
    }
    


  • Ruvi schrieb:

    Je nachdem wie "schwer" die Variable ist kann das ziemlich ineffizient und teuer sein. Wenn Du schon C++ programmierst dann solltest Du darauf achten den Code nicht unnoetigerweise "langsamer" zu machen.

    Also ist der Sinn einer cost referenz hauptsächlich die Optimierung des Programms, damit es schneller läuft. Gibt es sonnst noch Fälle, wo man eine cost refernez als Rückgabewert bracht, damit das Programm überhaupt laufen kann?


  • Mod

    win8789 schrieb:

    Also ist der Sinn einer cost referenz hauptsächlich die Optimierung des Programms, damit es schneller läuft. Gibt es sonnst noch Fälle, wo man eine cost refernez als Rückgabewert bracht, damit das Programm überhaupt laufen kann?

    Es gibt auch jede Menge Objekte, die konzeptionell nicht kopierbar sind, etwa weil sie eine einzigartige Ressource darstellen. Die Streams sind ein vertrautes Beispiel dafür.



  • SeppJ schrieb:

    Die Streams sind ein vertrautes Beispiel dafür.

    Wobei man die meist nicht const haben will. Sinnvolle Fälle in denen man nur const Reference verwenden kann sind wohl selten.


Log in to reply