2017-04-14 8 views
6

Mam kawałek koduPrzenieść konstruktora na zniszczony obiekt?

#include <iostream> 

class A { 
public: 
    A() { 
     std::cout << "Default constructor" << std::endl; 
    } 
    A(const A & other) 
    { 
     std::cout << "Copy constructor" << std::endl; 
    } 
    A(A && other) 
    { 
     std::cout << "Move constructor" << std::endl; 
    } 
    ~A() 
    { 
     std::cout << "Destructor" << std::endl; 
    } 
private: 
    int i; 
}; 

A && f() 
{ 
    return A(); 
} 

int main() { 
    A a = f(); 
} 

Próbowałem uruchomić go i wyjście okazuje się

Default constructor 
Destructor 
Move constructor 
Destructor 

Moje pytanie jest Dlaczego destruktor jest wywoływana przed przeniósł konstruktora? Czy to też oznacza, że ​​drugi obiekt został skonstruowany ze zniszczoną wartością?

+5

Nie powinieneś zwracać (rvalue-) odniesienia zmiennej tymczasowej. – Jarod42

+0

@ FrançoisAndrieux powinno to być odpowiedzią – Slava

+0

Zarówno GCC, jak i VC powinny domyślnie generować ostrzeżenie kompilatora. W każdym przypadku oba * mogą * ostrzec cię, jeśli ustawisz odpowiedni poziom ostrzeżenia. –

Odpowiedz

6

Zwrócenie zmiennej lokalnej z A && f() ma ten sam problem co A & f(). Oba są odniesieniami. Do czasu skonstruowania a w main() zmienna lokalna została zniszczona. Powoduje to odwołanie do zniszczonego wystąpienia prowadzącego do niezdefiniowanego zachowania.

Jeśli chcesz przenieść A() z f() na a w main po prostu zwrócić przez wartość. Spróbuj użyć następującego:

A f() { 
    return A(); 
} 
0

Pierwszy obiekt A został utworzony w ramce stosu wywołań f. Więc kiedy f zwróci kontrolę do main, wszystkie obiekty stosu, które zostały utworzone wewnątrz f, będą musiały zostać zniszczone. Właśnie dlatego został wywołany pierwszy destruktor.

+2

To jest zorientowany na implementację opis tego, co się dzieje. Z języka POV, to, co się tutaj dzieje, jest po prostu nieokreślonym zachowaniem. –

+0

@ChristianHackl dzięki za szczegóły. Chciałbym przeczytać więcej na ten temat. Wszelkie odniesienia lub linki? :) –

+0

Cóż, pojawi się nie więcej niż proste wyszukiwanie w Google dla "niezdefiniowanego zachowania C++". Jednak http://en.cppreference.com/w/cpp/language/ub może być dobrym początkiem. –

Powiązane problemy