Ist es effizienter, eine const-Referenz zurückzugeben?

8

z. B.

Was ist das Beste aus diesen:

%Vor%

oder

%Vor%     
Blair Conrad 09.11.2008, 10:06
quelle

3 Antworten

30

Eine Funktion sollte niemals einen Verweis auf ein lokales Objekt / eine lokale Variable zurückgeben , da solche Objekte den Gültigkeitsbereich verlassen und bei der Rückkehr der Funktion zerstört werden.

Anders ausgedrückt kann die Funktion einen konstanten oder nicht konstanten Verweis auf ein Objekt zurückgeben, dessen Bereich nicht durch den Funktionskontext begrenzt ist. Ein typisches Beispiel ist eine benutzerdefinierte operator<< :

%Vor%

Leider hat die Rückgabe von Werten ihren Leistungsnachteil. Wie von Chris erwähnt, beinhaltet die Rückgabe eines Objekts nach Wert die Kopie eines temporären Objekts und dessen anschließende Zerstörung. Die Kopie erfolgt entweder mit dem Kopierkonstruktor oder operator =. Um diese Ineffizienz zu vermeiden, können intelligente Compiler die RVO- oder NRVO-Optimierungen anwenden, aber es gibt Fälle, in denen sie nicht können - Mehrfachrückgaben.

Der kommende C ++ 0x-Standard, der teilweise in gnu gcc-4.3 verfügbar ist, führt die rvalue-Referenz [& amp; & amp;] ein, die verwendet werden kann, um einen L-Wert von einem R-Wert-Bezug zu unterscheiden. Dadurch ist es möglich, den move -Konstruktor zu implementieren, der nützlich ist, um ein Objekt zurückzugeben, wobei die Kosten des Kopierkonstruktors und des Destruktors des Temporären teilweise vermieden werden.

Der Move-Konstruktor ist das, was Andrei vor einigen Jahren in dem von Chris vorgeschlagenen Ссылка vorgeschlagen hat.

Ein move-Konstruktor hat die folgende Signatur:

%Vor%

und es soll das Eigentum an den Interna des übergebenen Objekts übernehmen und dieses in einem Standardzustand belassen. Dadurch werden Kopien von Interna vermieden und die Zerstörung des Temporären erleichtert. Eine typische Funktionsfabrik hat dann die folgende Form:

%Vor%

Das std :: move () gibt eine R-Wert-Referenz von einem Objekt zurück. Last but not least erlauben move-Konstruktoren die Rückgabe von nicht kopierbaren Objekten durch Rückgabewerte.

    
Nicola Bonelli 09.11.2008 10:33
quelle
16

Ich möchte Nicolas ausgezeichnete Antwort hinzufügen. Ja, Sie dürfen niemals eine freie Referenz (z. B. einen Verweis auf eine lokale Variable) zurückgeben. In diesen Fällen gibt es jedoch drei nützliche Möglichkeiten, die Leistung zu verbessern:

  1. Rückgabewert-Optimierung (RVO): Sie geben nach Wert zurück, eliminieren jedoch das Kopieren, indem Sie nur eine return -Anweisung haben, die den Rückgabewert an Ort und Stelle erzeugt. Hier ist ein Beispiel für die Verwendung von RVO: Wie kann ich eine C ++ - Zeichenfolge in Tokens umwandeln?

  2. Benannte Rückgabewertoptimierung (NRVO): Sie geben nach Wert zurück und deklarieren die Rückgabewertvariable zuerst oben in der Funktion. Alle return -Anweisungen geben diese Variable zurück. Bei Compilern, die NRVO unterstützen, wird diese Variable im Rückgabewert-Slot zugewiesen und bei der Rückgabe nicht kopiert. z.B.,

    %Vor%
  3. Verwenden Sie shared_ptr oder ähnliches als Rückgabetyp; Dies erfordert, dass Sie Ihr Objekt auf dem Heap und nicht auf dem Stapel erstellen. Dies verhindert Dangling-Referenz-Probleme, während immer noch nicht das gesamte Objekt kopiert werden muss, nur der Smart Pointer.

Übrigens kann ich die Informationen über RVO und NRVO nicht gutschreiben; Sie kommen direkt aus Scott Meyers effektiveres C ++ . Da ich das Buch im Moment nicht bei mir habe, sind Fehler in meiner Beschreibung mein Tun, nicht Scott's. : -)

    
Chris Jester-Young 09.11.2008 10:51
quelle
2

Wenn Sie einen Verweis auf eine Variable zurückgeben, die für die Funktion lokal ist, werden Sie Probleme haben (abhängig vom Compiler und seinen Einstellungen).

Wenn Sie einen Verweis auf eine Instanz zurückgeben, die sich noch im Gültigkeitsbereich der Funktion befindet, wird sie schneller ausgeführt, da keine Kopie der Zeichenfolge erstellt wird.

Letzteres ist also (technisch) effizienter, funktioniert aber möglicherweise nicht wie erwartet, abhängig davon, worauf Sie einen Verweis zurückgeben.

    
OJ. 09.11.2008 10:19
quelle

Tags und Links