2009-03-30 14 views
15

Myślałem, że gdy funkcja zwraca obiekt na stosie do funkcji wywołującej, funkcja wywołująca otrzymuje kopię oryginalnego obiektu, ale destruktor pierwotnego obiektu jest wywoływany, gdy tylko stos się odwija. Ale w poniższym programie destruktor jest wywoływany tylko raz. Spodziewałem się, że zostanie wywołane dwa razy.Dlaczego destruktor nie jest wywoływany dla zwróconego obiektu z funkcji?

#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. 
} 

Ale "destruktor MyClass" jest drukowany tylko raz. Czy moje założenie jest błędne, czy coś tu się dzieje?

+0

Dlaczego piszesz: "MyClass obj = MyClass();" ? "MyClass obj;" wszystko będzie dobrze. To nie jest java;). –

+0

Tak, to z powodu programowania w Javie przed :) – Srikanth

+0

@EvanTeran "_Dlaczego piszesz:" MyClass obj = MyClass(); "?" MyClass obj; "zrobi to samo dobrze" to są ** nie ** równoważny w ogóle. – curiousguy

Odpowiedz

21

Jest to specjalny przypadek, w którym kompilator może zoptymalizować kopię: nazywa się to named return value optimization (NRVO). Zasadniczo kompilator przydziela pamięć dla obiektu zwracającego w witrynie wywołania i pozwala funkcji wypełnić tę pamięć bezpośrednio, zamiast tworzyć obiekt w wywołanej lokacji i kopiować go z powrotem. Współczesne kompilatory robią to rutynowo, kiedy tylko jest to możliwe (są sytuacje, w których nie jest to łatwe, ponieważ istnieje kilka ścieżek powrotu w funkcji, które zwracają różne instancje).

Powiązane problemy