Ist es in Ordnung, einen Verweis auf eine lokale Variable von einer Funktion zurückzugeben? Mit lokal meine ich, dass die Variable innerhalb der Funktion (auf dem Stapel, d. H. Ohne Verwendung von neu) erzeugt wird und ihr Bereich nur innerhalb dieser Funktion liegt. Ich habe widersprüchliche Antworten bekommen, als ich danach gesucht habe. 1) sagt, dass die Art der Verwendung korrekt ist, aber 2) widerspricht es.
1) Ссылка 2) Ссылка (unter dem Abschnitt "Referenzen und Sicherheit")
Welche von ihnen hat Recht?
Eine andere Frage, die ich hatte, ist, wenn 1) richtig ist, dann dienen die folgenden dem gleichen Zweck.
i) Int & amp; a = func (); ii) int a = func (); Dabei gibt func () einen Verweis auf einen int (lokale Variable in dieser Funktion) zurück.
In beiden oben genannten Fällen gibt es kein Kopieren des Rückgabewerts, nicht wahr? Ich möchte das Kopieren von Rückgabewerten verhindern, da der Rückgabewert groß sein könnte.
Vielen Dank im Voraus.
Raghava.
Wie alle anderen sagen, tu das nicht. Das Zurückgeben eines Verweises oder Zeigers auf eine lokale Variable ist immer falsch, da der Rückgabevorgang die lokale Variable loslässt und daher der Verweis oder Zeiger automatisch ungültig ist.
Das Kopieren ist möglicherweise kein Problem. C ++ - Compiler dürfen bei der Rückgabe von Funktionen Copy-Konstruktoren überspringen (die "Rückgabewert-Optimierung"), damit ein ausreichend intelligenter Compiler den Wert an Ort und Stelle aufbauen kann. Daher können Sie möglicherweise einen großen Wert ohne Kopieren zurückgeben. Probieren Sie es aus und sehen Sie; Sie können Output-Anweisungen vorübergehend in den Copy-Konstruktor setzen (wenn Sie einen geschrieben haben und nicht den automatisch generierten verwenden), um festzustellen, ob er tatsächlich aufgerufen wird.
Also, ohne zu rennen und zu versuchen, wissen Sie nicht, ob tatsächlich kopiert wird, und wenn ja, wie viel von einem Problem ist es. Wie immer, Zeit und Profil ein Lauf, um zu sehen, ob es ein Problem gibt und wenn ja, wo. Es ist fast nie sinnvoll, etwas zu tun, das riskant und / oder verwirrend ist, um die Leistung zu beschleunigen, bevor man Timing und Profiling durchführt.
Sie können einen Verweis auf eine statische lokale Variable in einer Funktion zurückgeben. Andernfalls ist es ein Notfallrezept, da die lokale Variable zerstört wird, sobald die Funktion zurückkehrt.
Es kann hilfreich sein, das gleiche Beispiel zu verwenden, das Sie in Ihrem Artikel angegeben haben erste Referenz.
EDIT 2:
Für Punkt ii in Ihrem Beitrag nehmen wir eine Funktion 'fn' wie gezeigt an
%Vor%Dies beinhaltet eine Kopie aus dem Lvalue des Ausdrucks 'fn'.
Es beinhaltet keine Kopie, wenn es
war %Vor%Wenn Sie eine Variable innerhalb der Funktion meinen, nein ... ist es immer Unsinn, eine Referenz darauf zurückzugeben. Es ist vollkommen in Ordnung, einen Verweis auf eine Elementvariable aus einer Elementfunktion zurückzugeben.
Um das Kopieren großer Datenstrukturen zu vermeiden. Bitte warten Sie, bis Sie tatsächliche Profildaten haben, die zeigen, dass Sie a) tatsächlich eine Kopie erstellen, und b) dass es sich tatsächlich um einen Flaschenhals handelt. "Vorzeitige Optimierung ist die Wurzel allen Übels", mag ein bisschen extrem sein, aber vorzeitige Optimierung verursacht sicherlich eine ganze Menge Schmerz und Ärger, während selten, wenn überhaupt, tatsächlich irgendeinen der Vorteile liefert, die diese Versuche erreichen sollen.
>Die Beispiele, die Sie bei Ihrem ersten Link sehen, sind völlig falsch. Diese Seite bei functionx.com ist Müll. Das Zurückgeben eines Verweises auf eine lokale (automatische) Variable ist immer ein Fehler, da Versuche, auf den zurückgegebenen Wert zuzugreifen, zu undefiniertem Verhalten führen.
Der zweite Link bringt es richtig.
Es ist nie in Ordnung, einen Verweis auf eine nicht statische lokale Variable von einer Funktion zurückzugeben. Die Variable verlässt den Gültigkeitsbereich, wenn die Funktion zurückkehrt, und daher verweist die Referenz auf ein zerstörtes Objekt.
Auch wenn dies im ersten Beispiel unter 1) scheinbar so funktioniert, wird diese schlechte Übung schnell mit Klassen scheitern, die einen Destruktor haben oder größer sind.
Es ist am besten, entweder einen Zeiger zurückzugeben, einen Verweis auf ein lokal-statisches Objekt zurückzugeben, einen Verweis auf eine Elementvariable zurückzugeben.
Wenn in diesem Fall das Objekt innerhalb der Funktion erstellt wird, die zurückgegeben werden soll, können Sie die C ++ 0x-Verschiebesemantik für Ihre große Klasse implementieren. Dies wäre möglicherweise in der Lage, eine "große Kopie" in ein paar Zeiger-Swaps zu verwandeln.
unter der Annahme, dass func einen Verweis auf einen Wert zurückgibt, der nach der Rückgabe der Funktion (statisch lokal oder global) existiert, dann
%Vor%sind ziemlich unterschiedlich
in (i) bezieht sich immer noch auf das Statische oder Globale. Durch das Abändern von a wird die ursprüngliche Variable
geändertin (ii) a ist eine lokale Kopie, die Änderung hat keine Auswirkungen auf die ursprüngliche Variable