2009-03-20 14 views
6

In einem previous question, es schien, dass eine einfache Rückgabewert-Funktion kopiert immer return Argument in die Variable zugewiesen wird.Kopieren Konstruktor vs. Rückgabewert Optimierung

Wird dies vom Standard gefordert oder kann die Funktion optimiert werden, indem die Variable 'assigned to' sogar innerhalb des Funktionskörpers aufgebaut wird?

struct C { int i; double d; }; 

C f(int i, int d) { 
    return C(i,d); // construct _and_ copy-construct? 
} 

int main() { 
    C c = f(1, 2); 
} 

Antwort

7

Der Standard ermöglicht es jeder Ebene der Kopie Auslassung hier:

  • eine lokale temporäre konstruieren, Copy- konstruieren sie in einen Rückgabewert, und den Rückgabewert in das lokale „c“ copy-konstruieren. ODER
  • Konstruieren Sie eine lokale temporäre und kopieren Sie das in "c". OR
  • Konstrukt „c“ mit den Argumenten „i, d“
+0

Könnten Sie bitte die Abschnittsnummer aus dem Standard angeben? –

+0

Das gleiche, das Neil gepostet hat: 12.15. Interpretieren Sie es anders? –

7

Der Standard besagt, dass der Copy-Konstruktor muss nicht verwendet werden - siehe Abschnitt 12.8/15:

15 Jedes Mal, wenn ein temporäres Klassenobjekt kopiert wird eine Kopie Konstruktor, und diese Aufgabe und die Kopie haben die gleichen cv-unqualifizierten Typ, eine Implementierung ist erlaubt zu behandeln das Original und die Kopie als zwei verschiedene Möglichkeiten der Bezugnahme auf die gleichen Objekts und keine Kopie bei alle, auch wenn die Klasse kopieren Konstruktor oder Destruktor haben Seite Effekte.

Und vieles mehr in einer ähnlichen Ader.

+0

12.5 in meinem 1998 Standard ist "Free Store" beziehen Sie sich auf einige andere Standard? –

+0

hätte 12,8/15 sein sollen –

-1

ein Es ist sehr einfach und gute Möglichkeit, solche Überlegungen vollständig zu vermeiden - Sie können eine boost :: shared_ptr auf das erstellte Objekt betrachten Rückkehr - Es wird praktisch dasselbe sein, wenn es um Benutzerfreundlichkeit geht, aber Ihr Objekt wird sicher nicht unnötigerweise kopiert werden - und es wird auch wahr sein, wenn Sie es durch ein paar Schichten von Funktionsaufrufen zurückgeben.

+0

ist es nicht gut, shared_ptr std :: string oder std :: pair oder std :: vector. –

+0

Um den Kopieraufbau zu vermeiden, könnte ich heap i.s.o. Stapelspeicher. Ich weiß das:)/ Aber ich wollte wissen, ob ich den Compiler, d. H. Den Standard zu _Garantie_ rufen kann, meine Kopie Konstruktor aufrufen. Was ich nicht kann. – xtofl

+0

Neugierig: Warum brauchen Sie diese Garantie sowieso xtof? –

0

Weise Parameter nicht durch Referenz übergeben und Ergebnis zuweisen?

+0

, weil es hässlicher und weniger flexibel auf der Anrufseite ist. es sollte nur an leistungskritischen Stellen gemacht werden. –

+0

Oder wenn Sie mehrere Rückgabewerte benötigen (z. B. einen Status und einen Wert) – xtofl