If I understand correctly, a weak_ptr
doesn't increment the reference count of the managed object, therefore it doesn't represent ownership. It simply lets you access an object, the lifetime of which is managed by someone else.
So I don't really see why a weak_ptr
can't be constructed from a unique_ptr
, but only a shared_ptr
.
Can someone briefly explain this?
std::weak_ptr
can't be used unless you convert it to std::shared_ptr
by the means of lock()
. if the standard allowed what you suggest, that means that you need to convert std::weak_ptr to unique in order to use it, violating the uniqueness (or re-inventing std::shared_ptr
)
In order to illustrate, look at the two pieces of code:
std::shared_ptr<int> shared = std::make_shared<int>(10);
std::weak_ptr<int> weak(shared);
{
*(weak.lock()) = 20; //OK, the temporary shared_ptr will be destroyed but the pointee-integer still has shared to keep it alive
}
Now with your suggestion:
std::unique_ptr<int> unique = std::make_unique<int>(10);
std::weak_ptr<int> weak(unique);
{
*(weak.lock()) = 20; //not OK. the temporary unique_ptr will be destroyed but unique still points at it!
}
That has been said, you may suggest that there is only one unique_ptr
, and you still can dereference weak_ptr
(without creating another unique_ptr
) then there is no problem. But then what is the difference between unique_ptr
and shared_ptr
with one reference? or moreover, what is the difference between a regular unique_ptr
and C-pointers an get by using get
?
weak_ptr
is not for "general nonowning resources", it has a very specific job - The main goal of weak_ptr
is to prevent circular pointing of shared_ptr
which will make a memory leak. Anything else needs to be done with plain unique_ptr
and shared_ptr
.