2015-06-16 8 views
12
unique_ptr<A> myFun() 
{ 
    unique_ptr<A> pa(new A()); 
    return pa; 
} 

const A& rA = *myFun(); 

Dieser Code kompiliert, aber rA enthält Müll. Kann mir jemand erklären, warum dieser Code ungültig ist?Dereferenzieren einer temporären unique_ptr

Hinweis: Wenn ich die Rückgabe von myFun an eine Variable namens unique_ptr vor der Dereferenzierung zuweisen, funktioniert es gut.

+2

Da Sie das 'unique_ptr' nicht speichern, das' myFun' zurückgibt, wird sein Destruktor am Ende des Ausdrucks aufgerufen, und das Objekt, das ihm gehört, wird freigegeben. –

+0

@buttifulfulbuttefly Ich sah, dass in der Desassembly ich nicht verstehe, wie der Destruktor Aufruf ausgelöst wird. – Kam

+9

[Wie im Fernsehen gesehen] (https://www.youtube.com/watch?v=hEx5DNLWGgA#t=44m2s) –

Antwort

8

Die unique_ptr wird den Besitz an einen anderen unique_ptr übergeben, aber in Ihrem Code gibt es nichts, um die Eigentumsrechte von dem zurückkehrenden Zeiger zu erfassen. Mit anderen Worten: Es kann das Eigentum nicht übertragen, also wird es zerstört. Der richtige Weg ist:

unique_ptr<A> rA = myFun(); // Pass the ownership 

oder

const A rA = *myFun(); // Store the values before destruction 

In Ihrem Code, wird der zurückkehrende Zeiger desructed und der Verweis auf ein Objekt wird beziehe die bald zerstörende, nach, dass diese Referenz aufruft mit ein undefiniertes Verhalten.

5
unique_ptr<A> myFun() 
{ 
    unique_ptr<A> pa(new A()); 
    return pa; 
} 

const A& rA = *myFun(); 

Was Sie auf der letzten Zeile tat

unique_ptr<A>* temporary = new unique_ptr<A>(nullptr); 
myFun(&temporary); 
const A& rA = *temporary.get(); 
delete temporary; // and free *temporary 

Wenn Sie temporary löschen es hat einen Vertrag mit Ihnen, dass es den Zeiger und den Speicher besitzt, die bezieht. So zerstört es die A und gibt den Speicher frei.

In der Zwischenzeit haben Sie einen Verweis auf diesen Speicher als Verweis auf das Objekt an dieser Adresse schleichend gehalten.

Sie könnten entweder den Zeiger auf eine lokale unique_ptr übertragen:

unique_ptr<A> a = myFun(); 

oder Sie können die Objekte kopieren:

A = *myFun().get(); 

Das 'A' auf die myFun() s vorübergehend nur an der destructed Abschluss der Aussage, so ist es für die Kopie vorhanden.