rückgabe per reference



  • hi, in welchen fällen benutzt man denn die rückgabe per reference bsp int &test()... ??? Vorteile??? Welche Methode würde man für komplette Klassen bevorzugen???
    Mfg dohan



  • Vorteile:
    Bei der Rückgabe per Referenz wird keine Kopie erzeugt.
    string test() { string s("muh"); return s; }
    Hier wird ein string objekt erzeugt. Speicher muss für "muh" geholt werden. Das ist langsam. Danach muss wieder neuer Speicher geholt werden, "muh" rüberkopiert werden. Langsam. Alter Speicher wird freigegeben.
    Häufig optimieren das Compiler so (nennt sich name returned by value optimation o.ä.):
    string& test(string& in)
    {
    in = "muh"
    };
    Beim Aufruf von muh wird dann
    test(); durch folgendes ersetzt
    string tmp;
    test(in);
    So gibs keine Kopien. Das kann man natürlich auch selbst von Hand schreiben.



  • Ein weitere nützlich Fall sind Member.

    class
    {
      private:
        string muh;
      public
        string getString(); // String soll ja nicht veränderbar sein deswegen gibs ne Kopie zuück
    };
    class
    {
      private:
        string muh;
      public
        const string& getString(); // String soll ja nicht veränderbar sein deswegen ne const Reference. Wenn der Benutzer mitm String arbeiten will, soll er sich selbst ne Kopie machen.
    };
    


  • Bei Klassen sollte man referenzen bevorzugen, falls sie einen Copyconstructor und nicht built-in Typen benutzt. Aber denk dran:

    string& test()
    {
      string absturz;
      return absturz; 
    }// Hier wird absturz zerstört da der Funktionsnamespace verlassen wird. Du gibst eine Referenz auf ein Objekt das nicht existiert zurück.
    


  • Ich finde, die Rückgabe von Referenzen sollte möglichst vermieden werden!

    Klar hat Lars recht, daß bei Rückgabe von Objekten ein Kopiervorgang anfällt, und das kann ein Nachteil sein. In sofern wäre die Rückgabe einer Referenz besser. Aber erstaunlich oft (und gerade bei std::string) ist dieser Vorteil aber keiner als man glaubt.

    Im Falle von Member-Variablen handelt man sich bei Rückgabe von Referenzen einen gravierenden Nachteil ein, den Lars leider nicht erwähnt. Es wird nämlich ein Implementierungsdetail der Klasse offenbart: Der zurückgegebene Wert muß eine Member-Variable des angegebenen Typs (oder einer Unterklasse) sein. Das verletzt das fundamentale Prinzip der OO, nämlich das information hiding. Die Rückgabe einer Referenz ist in diesem Sinne fast so schlimm wie die Variable public zu machen. Gebe ich hingegen ein Objekt zurück, bleibt die Repräsentation der Daten verborgen, so daß ich die Freiheit habe, sie (ggf. bei einem späteren Redesign) ganz anders zur repräsentieren, ohne daß die Schnittstelle der Klasse geändert werden muß.

    Stefan.



  • Original erstellt von <StefanD>:
    **
    Im Falle von Member-Variablen handelt man sich bei Rückgabe von Referenzen einen gravierenden Nachteil ein, den Lars leider nicht erwähnt. Es wird nämlich ein Implementierungsdetail der Klasse offenbart: Der zurückgegebene Wert muß eine Member-Variable des angegebenen Typs (oder einer Unterklasse) sein. Das verletzt das fundamentale Prinzip der OO, nämlich das information hiding. Die Rückgabe einer Referenz ist in diesem Sinne fast so schlimm wie die Variable public zu machen. Gebe ich hingegen ein Objekt zurück, bleibt die Repräsentation der Daten verborgen, so daß ich die Freiheit habe, sie (ggf. bei einem späteren Redesign) ganz anders zur repräsentieren, ohne daß die Schnittstelle der Klasse geändert werden muß.**

    Das stimmt schlichtweg nicht. const Referenzen gehen da in Ordnung



  • lösung: const reference



  • Das stimmt schlichtweg nicht. const Referenzen gehen da in Ordnung

    Tja, so könnte man jetzt weiter machen: Das stimmt schlichtweg nicht....
    Nimm ein Beispiel:

    class Test {
    public:
       const std::string &getValue() const { return _value; }
    private:
       std::string _value;
    };
    

    Jetzt nimm z.B. an, daß die Rückgabe von getValue() immer zur Laufzeit berechnet werden muß; oder daß die Instanzvariable ein char-buffer sein soll, oder was auch immer. Das geht bei Rückgabe einer Referenz nicht, ohne die Rückgabe von getValue() zu ändern - es sei denn man steht auf wirklich grausame Klimmzüge.
    Ich bleibe dabei: Eine Referenz (ob const oder nicht) als Rückgabe einer Methode verletzt das Prinzip des information hiding und sollte deshalb vermieden werden.

    Stefan.



  • Information Hiding heißt ja nicht, dass der Verwender einer Klasse nicht wissen darf, wie sie das intern macht, sondern, dass ers nicht wissen muss, weils Ihm egal sein kann.

    Und ob man ne const-Referenz oder ne Kopie zurückgibt ist - wenn man jetzt mal davon ausgeht, dass es sich um eine einfach Struktur handelt, die problemlos kopiert werden darf - für den Benutzer genau dasselbt -> es werden keine OO-Prinzipien verletzt.

    Einziger Unterschied: Der benutzer könnte das const wegcasten und meine Daten ändern. Aber ich denk, dann isser selber Schuld. Weil Wege, mutwillig die Kapselung zu umgehen gibts genug. Das kann man eh nicht verhindern, falls ein Progger so blöd sein sollte.



  • ich denke mal, dass rückgabe einer referenz was ziemlich gefärhliches ist: was passiert zum beispiel hier:

    MyClass &myC() { MyClass c; return c; }
    MyClass a = myC();
    

    hier erstelle ich doch zunächst mal das lokale objekt c, und gebe die referenz an den aufrufer zurück. aber nach dem ich die funktion verlassen habe, ist das objekt ja aufgrund der erlöschenden gültigkeit gelöscht worden. ein zugriff dürfte also nicht möglich sein



  • @Korbinian
    Darüber disktuieren die Jungs hier nicht.
    Es geht hier um die Rückgabe von Referenzen auf Instanzvariablen und die Leben so lange wie das entsprechende Objekt.

    Ich würde hier übrigens keine allgemeine Regel propagieren. Ich halte es da mit Martin Fowler und seinen "Hide Delegate" und "Remove Middle Man" Refactorings. Mal macht es mehr Sinn eine Schnittstelle zu verdoppeln oder eine Instanzvariable per Value zu liefern und Mal macht es mehr Sinn mit Referenzen zu arbeiten. Ich würde das ganze auf jeden Fall nicht vorzeitig nur aus Performace-Sicht betrachten.



  • und wie erkennt man was in welchem fall besser ist? 🙄


Anmelden zum Antworten