A weak/shared pointer, detect when one user remains, boost
I want a pointer where I can tell when the reference count is one. Essentially the pointer works like a weak_ptr, but the cleanup needs to be manual. That is, every so often the program goes through a loop of its pointers and checks which ones have only one reference remaining. Some it will clean, others it will retain a while longer (in case somebody needs it again).
Now, I know how to do this using a combination of a custom cleanup function and weak_ptr. I just think the same thing could be accomplished, with simpler code, if I could simply figure out when only one user of the shared_ptr remains.
I know that shared_ptr has a use_count
function, but it has this ominous note in the docs: "...not necessarily efficient. Use only for debugging and testing purposes..." Naturally I'm not so keen on using something with such a warning. I don't really need the count anyway, just a way to det开发者_Python百科ect when there is only one left.
Is there some boost wrapper that achieves what I want (can be in any library)? Or must I use the technique I already know of custom cleanup function combined with a weak_ptr?
You cannot in general accurately determine the number of references. But you can tell when it is exactly one - use unique()
.
Destructively transform your shared_ptr
s into weak_ptr
s and then to shared_ptr
s back again, except that some of those will be null. Of course there's no telling how that fares for performance, but given the interface we have it's either that or use_count
.
Could look like:
std::for_each(begin, end, [](element_type& pointer)
{
std::weak_ptr<element_type::element_type> weak = element_type(std::move(pointer));
pointer = weak.lock();
});
auto predicate = [](element_type& pointer) { return !pointer; };
container.erase(std::remove_if(begin, end, predicate), end);
When you're doing something complex that can't quite be represented with the normal shared_ptr system, you might want to consider using intrusive_ptr
instead - your implementation of intrusive_ptr_release
can then queue objects up for later destruction instead of deleting them immediately. Note that intrusive_ptr
can't be directly used with weak_ptr
, although you can construct your own variant of weak_ptr
if you prefer. Keep in mind, though, that if you are using multiple threads the reference counting may get a bit tricky.
If you can't use an intrusive pointer, and it's acceptable to invalidate existing weak_ptr
s when the last shared_ptr
is lost, you can have the destructor for the shared_ptr
put the raw pointer back into your cache (or whatever) marked for eventual cleanup. You can rewrap it in a shared_ptr
the next time it is retrieved. However, again, this has the downside of losing all weak_ptr
s to the object at the moment of pseudo-destruction.
If you can't use an intrusive pointer, you may be best off simply designing your own smart pointer implementation. Unfortunately, shared_ptr
does not have the kind of hooks needed to implement your goals efficiently, so you may be working from scratch.
精彩评论