Reputation: 3775
Asking a dumb question. From what I understand one usage of weak_ptr is to check the count status of shared pointer on an object. Couldn't we just use the shared_ptr use_count() to get this info. If so why need weak_ptr?
As an example:
#include <memory>
#include <cassert>
using namespace std;
int main() {
shared_ptr<int> a(new int(10));
weak_ptr<int> wa(a);
a.reset();
assert(a.use_count() == 0); // clause 1 - good. indicate no binding objects
assert(wa.lock() == nullptr); // clause 2 - good. same as above
return 0;
}
Clause 1 & 2 produces identical results.
So why need weak_ptr (putting aside thread safety) to test for null binding objects when shared_ptr.use_count() can do the job?
Thanks.
Upvotes: 0
Views: 168
Reputation: 16803
From what I understand one usage of weak_ptr is to check the count status of shared pointer on an object.
This is not a common use, in part because it is gratuitously complicated. If you have a shared_ptr
and want to know if its use count is zero, you can get that information directly from the shared_ptr
. There is no need to construct a weak_ptr
for this task.
In fact, constructing a weak_ptr
is typically pointless unless it has a different lifetime than the shared_ptr
from which it is constructed. It's only when the source shared_ptr
is not accessible that a weak_ptr
has value. At which point, there is no question that the weak_ptr
is needed.
So why need weak_ptr (putting aside thread safety) to test for null binding objects when shared_ptr.use_count() can do the job?
If you have a shared_ptr
available, you do not need a weak_ptr
to the same object. But do not use use_count
to check the status of the pointer (or for anything other than debugging). Instead, use get
or just use the shared_ptr
in a boolean context. That is, given shared_ptr<int> a;
one can test the "count status" simply by if (a)
, where truth means a
manages an object / has a use count greater than zero, and falsity means a
does not manage an object / has a use count of zero.† (Some people prefer if (a != nullptr)
for greater clarity.)
To put it in terms of your example code:
#include <memory>
#include <cassert>
int main() {
std::shared_ptr<int> a(new int(10));
a.reset();
assert(!a); // clause 3 - good. indicate no binding objects
}
† To be pedantic, there is a pathological case where a shared pointer could be non-null yet not manage an object. However, this results from (mis-)use of the aliasing constructor, not reset()
. The aliasing constructor is an advanced topic, so let's skip it here.
Upvotes: -1
Reputation: 43188
No, no we cannot.
The idea of weak_ptr
is we want to have a reference to something but not keep it alive ourselves; that is when the strong references go away, so does the object; and when we resolve the weak pointer we get a null back.
One example of a weak_ptr
might be in a binary tree; suppose every node needs a reference to its parent node. If you used shared_ptr
to reference the parent node you would have a cycle which results in a memory leak, but the weak_ptr
on the parent node doesn't.
There are other uses for weak pointers where you can have a reference to some large object from a place unrelated to its actual lifetime; but constructing a small easy to understand example is not trivial.
Upvotes: 1