开发者

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_ptrs into weak_ptrs and then to shared_ptrs 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_ptrs 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_ptrs 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜