Ref's als Rückgabewert
-
Hallo!
In den Beispiel Listings in meinem Buch werden oft irgendwelche Objekte als Referenzen rückgegeben (von Funktionen). Ich verstehe noch nicht ganz den Zweck dahinter, warum man nicht das Objekt selbst returned. Also im Fall wo das Objekt als Parameter auftaucht verstehe ich den Unterschied: Übergibt man das Objekt, so wird eine Kopie des Objekts angelegt und die Funktion operiert auf der Kopie. Übergibt man als Referenz, so operiert die Funktion tatsächlich genau auf diesem Objekt. Aber wie sieht es eben bei der Rückgabe aus?
-
Wenn ein Objekt zurückgegeben wird, dann wird eine Kopie des Objektes in der Funktion an den Code außerhalb der Funktion weitergegeben. Bei Referenzen eben nicht. Allerdings kann man nur dann eine Referenz zurückgeben, wenn es sich nicht um ein Ojekt handelt, das lokal in der Funktion erzeugt wurde. Die werden nämlich beim verlassen der Funktion zerstört (deshalb auch die Kopie bei der normalen Rückgabe) und die Referenz wäre ungültig.
-
ja genau das hatte ic mir auch gedacht zuerst. dann habe ich aber mal zum teste folgendes kompiliert und ausgeführt:
#include <iostream> using namespace std; int function(int zahl) { return zahl; } int main() { int i = 0; cout << &i << endl; int j = function(i); cout << &j << endl; return 0; }bei mir kam da 2mal die gleiche adresse raus. deshalb hatte ich den thread erstellt. jetzt zur antwort habe ich den code nochmal kompiliert und ausgeführt. jetzt komischerweise kommen verschiedene adressen raus. ergo bin ich momentan verwirrt. ^^
-
Wieso soll auch die gleiche Adresse herauskommen, i und j sind ja zwei unterschiedliche Variablen. Dass das beim ersten Mal anders gewesen sein soll, kann ich mir nicht vorstellen.
Hat aber irgendwie nicht viel mit der Ursprungsfrage zu tun, oder?
-
mit dem code wollte ich eig testen, ob der rückgabewert eine kopie von dem ist, was in der funktion als rückgabewert deklariert wird. sehe aber jetzt auch, dass der code dieses ziel auch verfehlt. ^^ aber die frage ist schon beantwortet: der rückgabewert ist genau wie im fall des parameters eine kopie, es sei denn ich gebe als ref (oder als zeiger) zurück. in diesem fall bekomme ich tatsächlich das in der funktion deklarierte objekt zurück. stimmt so, oder?
-
in diesem fall bekomme ich tatsächlich das in der funktion deklarierte objekt zurück. stimmt so, oder?
Ja, wobei lokale Objekte beim Verlassen der Funktion wieder zerstört werden, wie pumuckl ja schon gesagt hat.
Gibt übrigens auch noch RVO. Je nachdem stehen deine Chancen also gut, dass beim Zurückgeben als Wert gar keine Kopie angefertigt werden muss.
-
cyau schrieb:
#include <iostream> using namespace std; int function(int zahl) { return zahl; } int main() { int i = 0; cout << &i << endl; int j = function(i); cout << &j << endl; return 0; }bei mir kam da 2mal die gleiche adresse raus.
Interessant! Bleibt das auch so, wenn du statt
return 0;einfachreturn i;schreibst oder den Parameter in "function" per referenz-auf-const entgegen nimmst? Ich könnte mir vorstellen, dass das Ergebnis dann anders ist. Ansonsten könnte der Compiler den Platz von i für j recycelt haben, weil die Adresse von i nicht in eine andere Funktion "entflieht" und i nicht mehr gebraucht wird wenn j erstellt/benutzt wird.Mit welchem Compiler/Optionen hast Du das getestet?
Gruß,
SP
-
wie gesagt, beim zweiten mal kamen versch. adressen raus, vielleicht hab ich mich beim ersten mal auch nur vertan irgendwo.
danke für die antworten soweit.
-
Sebastian Pizer schrieb:
cyau schrieb:
#include <iostream> using namespace std; int function(int zahl) { return zahl; } int main() { int i = 0; cout << &i << endl; int j = function(i); cout << &j << endl; return 0; }bei mir kam da 2mal die gleiche adresse raus.
(...)
Ansonsten könnte der Compiler den Platz von i für j recycelt haben, weil die Adresse von i nicht in eine andere Funktion "entflieht" und i nicht mehr gebraucht wird wenn j erstellt/benutzt wird.Naja, laut Standard wäre das IMO nicht erlaubt. Der Standard sagt IIRC dass zwei unterschiedliche "Dinge" (i und j in dem Fall) nicht die gleiche Adresse haben dürfen. Da i und j sich bis zum Ende der Funktion noch im Scope befinden, darf ihre Adresse also auch nicht gleich sein. Was hier an Optimierungen möglich wäre oder nicht, ist auch egal, da der Compiler sich ja an die "as if" Regel halten muss.
Falls du anderer Meinung bist, würde mich interessieren wo deiner Meinung nach mein Denkfehler liegt

-
hustbaer schrieb:
Naja, laut Standard wäre das IMO nicht erlaubt.
Ja, kann ich mir gut vorstellen. Ich hatte mich einfach auf die Lesefähigkeiten von cyau verlassen.
hustbaer schrieb:
[...] die "as if" Regel [...]
Du hast vollkommen Recht.