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 another unique_ptr
does not change the location of the object itself, and that get()
on the second unique_ptr
returns the same as it would have on the first unique_ptr
before the transfer.
Looking at N3337, section 20.7.1:
Additionally, u
can, upon request, transfer ownership to another unique pointer u2
. Upon completion of such a transfer, the following
postconditions hold:
u2.p
is equal to the pre-transfer u.p
,
u.p
is equal to nullptr
, and
- if the pre-transfer
u.d
maintained state, such state has been transferred to u2.d
.
where u
is a unique_ptr
object that stores a pointer u.p
.
The first bullet answers the question directly, since get()
is specified as returning the u.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 another unique_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.