Consider the following code snippet:
class Owner {
public:
Owner(std::unique_ptr<int> ptr) : owned_pointer<int>(std:move(ptr)) {}
private:
std::unique_ptr<int> owned_pointer;
};
std::unique_ptr<int> ptr(new int);
int* ptr1 = ptr.get();
Owner new_owner(std::move(ptr));
Is it safe to assume that ptr1 is valid as long as new_owner stays in scope? It seems to work, but I can't find a specification that states that explicitly - is it undefined behavior/implementation specific and just happen to work for me, or the code posted above is valid (ptr1 is guaranteed to point to moved pointer as long as it stays alive)?
Yes, the C++11 specification guarantees that transferring ownership of an object from one
unique_ptr
to anotherunique_ptr
does not change the location of the object itself, and thatget()
on the secondunique_ptr
returns the same as it would have on the firstunique_ptr
before the transfer.Looking at N3337, section 20.7.1:
where
u
is aunique_ptr
object that stores a pointeru.p
.The first bullet answers the question directly, since
get()
is specified as returning theu.p
.Yes, it is valid.
You can have multiple (plain) pointers pointing to the same object. The question is how long those pointers are valid or when the object pointed to is deleted.
A
unique_ptr
stores one more plain pointer and takes ownership, meaning it is responsible for when the object is destroyed. Moving it to anotherunique_ptr
just transfers ownership, the object itself is still the same and all plain pointers pointing to it remain valid.Only when the ownership is not transferred (or released) and the owning
unique_ptr
is destroyed, it also destroys the object. This would be the moment where all plain pointers pointing to the object become dangling pointers and dereferencing them would be illegal.