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?
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.
unique_ptr. An unique_ptr has exclusive ownership of the object it points to and will destroy the object when the pointer goes out of scope.
unique_ptr is a new facility with a similar functionality, but with improved security. auto_ptr is a smart pointer that manages an object obtained via new expression and deletes that object when auto_ptr itself is destroyed.
std::weak_ptr are pointers, so as with any pointer types, a = p; copy pointer, not the content of what is pointed. If you want to copy the content, you would need *a = *p; , but you cannot do that with weak_ptr , you need to lock() both a and p before.
Weak pointer CONCEPT doesn't disclaims unique_ptr usage. Weak pointer is only an information if the object has been already deleted so it's not a magic but very simple generalized observer pattern. It's because of threadsafety and consistency with shared_ptr.
tl;dr; weak_ptr depends on a weak reference count which is part of shared_ptr, there cannot be a weak_ptr without a shared_ptr. In effect, a weak_ptr is a shared_ptr to the reference count object. Conceptually, there is nothing preventing an implementation where a weak_ptr only provides access and a unique_ptr controls the lifetime.
A weak_ptr is created as a copy of shared_ptr. It provides access to an object that is owned by one or more shared_ptr instances but does not participate in reference counting. The existence or destruction of weak_ptr has no effect on the shared_ptr or its other copies.
the stored pointer of the shared_ptr it was constructed from. A separate stored pointer is necessary to ensure that converting a shared_ptr to weak_ptr and then back works correctly, even for aliased shared_ptr s. It is not possible to access the stored pointer in a weak_ptr without locking it into a shared_ptr .
If you think about it, a weak_ptr
must refer to something other than the object itself. That's because the object can cease to exist (when there are no more strong pointers to it) and the weak_ptr
still has to refer to something that contains the information that the object no longer exists.
With a shared_ptr
, that something is the thing that contains the reference count. But with a unique_ptr
, there is no reference count, so there is no thing that contains the reference count, thus nothing to continue to exist when the object is gone. So there's nothing for a weak_ptr
to refer to.
There would also be no sane way to use such a weak_ptr
. To use it, you'd have to have some way to guarantee that the object wasn't destroyed while you were using it. That's easy with a shared_ptr
-- that's what a shared_ptr
does. But how do you do that with a unique_ptr
? You obviously can't have two of them, and something else must already own the object or it would have been destroyed since your pointer is weak.
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
.
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