2009-03-30 6 views
15

Ich dachte, dass, wenn eine Funktion ein Objekt auf dem Stapel an die aufrufende Funktion zurückgibt, die aufrufende Funktion eine Kopie des ursprünglichen Objekts erhält, aber der Destruktor des ursprünglichen Objekts aufgerufen wird, sobald der Stapel abwickelt. Aber im folgenden Programm wird der Destruktor nur einmal aufgerufen. Ich habe erwartet, dass es zweimal angerufen wird.Warum wird der Destruktor nicht für das zurückgegebene Objekt von der Funktion aufgerufen?

#include <iostream> 

class MyClass 
{ 
public: 
    ~MyClass() { std::cout << "destructor of MyClass" << std::endl; } 
}; 

MyClass getMyClass() 
{ 
    MyClass obj = MyClass(); 
    return obj; // dtor call for obj here? 
} 

int main() 
{ 
    MyClass myobj = getMyClass(); 
    return 0; // Another dtor call for myobj. 
} 

Aber "destructor von MyClass" wird nur einmal gedruckt. Ist meine Annahme falsch oder geht hier etwas anderes vor?

+0

Warum schreiben Sie: "MyClass obj = MyClass();" ? "Meine Klasse obj;" geht es gut. Das ist nicht Java;). –

+0

Ja, es ist wegen der vielen Programmierung in Java vorher :) – Srikanth

+0

@EvanTeran "_Warum schreibst du:" MyClass obj = MyClass(); "?" MyClass obj; "wird es gut machen_" das sind ** nicht ** gleichwertig im Allgemeinen. – curiousguy

Antwort

21

Dies ist ein Spezialfall, bei dem der Compiler die Kopie optimieren darf: dies heißt named return value optimization (NRVO). Im Grunde reserviert der Compiler Speicher für das Rückgabeobjekt auf der Aufrufsite und lässt die Funktion diesen Speicher direkt ausfüllen, anstatt das Objekt an der aufgerufenen Site zu erstellen und es zurück zu kopieren. Moderne Compiler tun dies routinemäßig wann immer es möglich ist (es gibt einige Situationen, in denen dies nicht einfach ist, da es mehrere Rückkehrpfade in der Funktion gibt, die verschiedene Instanzen zurückgeben).

Verwandte Themen