弱/共享指针,检测一个用户何时剩余,提升

发布于 2024-12-06 18:35:39 字数 461 浏览 0 评论 0原文

我想要一个指针,可以在其中判断引用计数何时为一。本质上,指针的工作方式类似于weak_ptr,但清理需要手动进行。也就是说,程序时常会遍历其指针循环并检查哪些指针仅剩一个引用。有些它会清洁,有些会保留一段时间(以防有人再次需要它)。

现在,我知道如何使用自定义清理函数和weak_ptr 的组合来执行此操作。我只是认为,如果我能简单地弄清楚何时只剩下一个shared_ptr用户,那么用更简单的代码就可以完成同样的事情。

我知道shared_ptr有一个use_count函数,但它在文档中有一个不祥的注释:“...不一定有效。仅用于调试和测试目的...” 当然,我不太热衷于使用带有这样警告的东西。无论如何,我真的不需要计数,只是一种检测何时只剩下一个的方法。

是否有一些升压包装器可以实现我想要的(可以在任何库中)?或者我必须使用我已经知道的自定义清理函数与weak_ptr 相结合的技术吗?

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 detect 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

星星的轨迹 2024-12-13 18:35:39

一般来说,您无法准确确定参考文献的数量。但您可以判断它何时恰好为 1 - 使用 unique()

You cannot in general accurately determine the number of references. But you can tell when it is exactly one - use unique().

夏の忆 2024-12-13 18:35:39

破坏性地将您的 shared_ptr 转换为 weak_ptr,然后再次转换为 shared_ptr,但其中一些将为 null。当然,没有人知道它的性能如何,但考虑到我们拥有的接口,它要么是那个,要么是 use_count

可能看起来像:

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);

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);
蓝颜夕 2024-12-13 18:35:39

当您正在做一些无法用普通的shared_ptr系统完全表示的复杂事情时,您可能需要考虑使用 intrusive_ptr - 您的 intrusive_ptr_release 实现可以排队对象以便稍后销毁,而不是立即删除它们。请注意,intrusive_ptr 不能直接与 weak_ptr 一起使用,尽管您可以根据需要构造自己的 weak_ptr 变体。但请记住,如果您使用多个线程,引用计数可能会有点棘手。

如果您无法使用侵入式指针,并且当最后一个 shared_ptr 丢失时使现有的 weak_ptr 无效是可以接受的,那么您可以使用 shared_ptr 的析构函数原始指针放回标记为最终清理的缓存(或其他内容)中。您可以在下次检索它时将其重新包装在 shared_ptr 中。然而,同样,这也有一个缺点,即在伪销毁时会丢失对象的所有 weak_ptr

如果您不能使用侵入式指针,那么您最好简单地设计自己的智能指针实现。不幸的是,shared_ptr 没有有效实现您的目标所需的挂钩,因此您可能需要从头开始工作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文