2016-04-20 7 views
2

Es ist mein Verständnis, dass, nachdem ich von einem Standard-Bibliothek-Objekt umgezogen bin, dieses Objekt in einem Zustand ist, der gültig aber nicht definiert ist. Aber im Fall einer unique_ptr, wie undefiniert ist es? Empirisch scheint der Code unten zu funktionieren, das heißt, nachdem ich von p1 gehe, "if (p1)" wertet false aus. Intuitiv scheint dies das richtige Verhalten zu sein. Aber kann ich mich darauf verlassen?Ist `unique_ptr :: operator bool()` für ein unique_ptr definiert, von dem move() d stammt?

#include <memory> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    using namespace std; 

    unique_ptr<int> p1 {make_unique<int>(1)}; 
    unique_ptr<int> p2; 

    if (p1) 
     cout << "p1 owns an object" << endl; 
    if (p2) 
     cout << "p2 owns an object" << endl; 

    p2 = move(p1); 

    // Is the following test valid, now that p1 has been moved from? 
    if (p1) 
     cout << "p1 owns an object" << endl; 
    if (p2) 
     cout << "p2 owns an object" << endl; 
} 

Ausgang:

p1 owns an object 
p2 owns an object 

Antwort

7

Die unique_ptr ‚s-Spezifikation ausdrücklich, dass die Wirkung der Bewegungsoperationen auf solche Zeiger ist Übertragung des Eigentums von der rechten Seite Zeiger auf der linken Seitenzeiger (20.8.1/16 für den Bewegungskonstruktor, 20.8.1.2.3/2 für die Zuweisung). Das Konzept der Übertragung des Eigentums ist explizit in der Norm (20.8.1/4) definiert und besagt, dass die rechte Seite nullptr nach einer solchen Übertragung wird.

Das bedeutet, dass der Status oder die verschobene unique_ptr nicht nur gültig ist, es ist definiert.

1

kann ich mich darauf verlassen?

Ja, Sie können. Verschieben auf eine std::unique_ptr bedeutet Übertragung von Besitz von ihm, und dann operator bool wird false sicherlich zurückgeben, da es kein Objekt besitzt.