I've been led to understand that calling a member function on the contents of a moved-from std::unique_ptr
is undefined behaviour. My question is: if I call .get()
on a unique_ptr and then move it, will the original .get()
pointer continue to point to the contents of the original unique pointer?
In other words,
std::unique_ptr<A> a = ...
A* a_ptr = a.get();
std::unique_ptr<A> a2 = std::move(a);
// Does *a_ptr == *a2?
I think it does, but I want to make sure.
('contents' is probably the wrong word. I mean the data you get when you dereference the pointer)
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.
In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
Merely moving the unique_ptr
only changes the ownership on the pointed-to object, but does not invalidate (delete) it. The pointer pointed to by unique_ptr<>::get()
will be valid as long as it hasn't been deleted. It will be deleted, for example, by the destructor of an owning unique_ptr<>
. Thus:
obj*ptr = nullptr; // an observing pointer
{
std::unique_ptr<obj> p1;
{
std::unique_ptr<obj> p2(new obj); // p2 is owner
ptr = p2.get(); // ptr is copy of contents of p2
/* ... */ // ptr is valid
p1 = std::move(p2); // p1 becomes new owner
/* ... */ // ptr is valid but p2-> is not
} // p2 destroyed: no effect on ptr
/* ... */ // ptr still valid
} // p1 destroyed: object deleted
/* ... */ // ptr invalid!
Of course, you must never try to use a unique_ptr
that has been moved from, because a moved-from unique_ptr
has no contents. Thus
std::unique_ptr<obj> p1(new obj);
std::unique_ptr<obj> p2 = std::move(p1);
p1->call_member(); // undefined behaviour
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With