In den drei Fällen, die zweite Zeile ist gemeinsam:
MyType t = myFunction();
Diese Linie das Ergebnis bekommt myFunction
aufrufen und verwendet es, um copy-Konstrukt ein neues Element der MyType
t
genannt.
Nun zu den Unterschieden. Im ersten Fall geben Sie nach Wert zurück, was bedeutet, dass der Compiler (semantisch) eine Kopie des Objekts erstellen wird, das sich in der return
-Anweisung innerhalb myFunction
befindet, und diese Kopie dann als Quelle für die Kopierkonstruktion von t
verwenden. Der Compiler wird höchstwahrscheinlich die Kopien (mindestens die zweite) kopieren. In den anderen beiden Fällen geben die Funktionen Referenzen an ein anderes Objekt zurück. Wenn es sich bei den Objekten um Einheimische handelt, handelt es sich um undefiniertes Verhalten. Der Unterschied zwischen den beiden besteht darin, ob der zurückgegebene Verweis verwendet werden kann, um das referenzierte Objekt zu ändern oder nicht, und dies könnte sich darauf auswirken, welcher Copy-Konstruktor verwendet wird oder ob es überhaupt verwendet werden kann. Beachten Sie, dass das Objekt, von dem Sie die Referenz erhalten, den Funktionsaufruf überleben muss, oder Sie werden ein undefiniertes Verhalten verursachen.
// an example where it matters:
typedef std::auto_ptr<int> MyType;
MyType t = myFunction();
std::auto_ptr
Weil die rechte Seite auf Zuweisung ändert, wird der vorherige Code nur funktionieren, wenn der zurückgegebene Bezug nicht-const ist.
Luchian weist darauf hin, dass die Rückgabe einer Referenz wird höchstwahrscheinlich undefiniert Verhalten sein, also wann wäre es nicht? Wenn das Objekt, von dem die Referenz erhalten wurde, die Verwendung der Referenz überlebt.Das ist der Grundbaustein des Meyers Singletons:
// an example where returning a reference is correct
MyType & myFunction() {
static MyType instance; // Note static storage duration!
return instance;
}
Oder jede Ebene accessor, die einen Verweis auf ein Unterobjekt zurückgibt. Einige der häufigsten Fälle sind operator[]
in Containern (sie kopieren normalerweise nicht den Wert, sondern geben einen Verweis auf die gespeicherten Daten zurück).
Aber es ist wahr, dass Funktionen oft nicht statisch gelebte Objekte, sondern Einheimische zurückgeben.
Neben dem Meyers-Singleton (das aus verschiedenen Gründen keine universelle Adhäsion hat) könnten Sie Site-Funktionen wie die '[]' -Operatoren in 'std :: vector' und' std :: map' verwenden. Sie sind wahrscheinlich häufigere Beispiele dafür, wo Referenzen für Rückgabewerte verwendet werden. –
@JamesKanze: Richtig, es gibt viele * Accessoren * in Klassen, die Referenzen zurückgeben sollten. Ich habe versucht, die Antwort auf freie Funktionen zu beschränken, so wie es bei der Frage der Fall zu sein scheint. Aktualisiert die Antwort, um dieses spezielle Beispiel zu enthalten. Vielen Dank. –