C++ Boost shared_ptr use_count函数

C++ Boost shared_ptr use_count函数,c++,boost,shared-ptr,C++,Boost,Shared Ptr,我的应用程序问题如下- 我有一个大的结构。因为它们很大,并且出于内存管理的原因,我们不希望在数据处理完成时删除它们 我们将它们存储在std::vector中。 我的问题与知道所有处理何时完成有关。第一个决定是,我们不希望任何其他应用程序代码在结构中标记一个完整的标志,因为程序中有多个执行路径,我们无法预测哪一个是最后一个 因此,在我们的实现中,一旦处理完成,我们将删除boost::shared\u ptr>的所有副本,向量中的副本除外。这将使共享ptr中的参考计数器降为1。使用shared_pt

我的应用程序问题如下-

我有一个大的结构。因为它们很大,并且出于内存管理的原因,我们不希望在数据处理完成时删除它们

我们将它们存储在
std::vector中。

我的问题与知道所有处理何时完成有关。第一个决定是,我们不希望任何其他应用程序代码在结构中标记一个完整的标志,因为程序中有多个执行路径,我们无法预测哪一个是最后一个

因此,在我们的实现中,一旦处理完成,我们将删除
boost::shared\u ptr>
的所有副本,向量中的副本除外。这将使共享ptr中的参考计数器降为1。使用shared_ptr是否可行。使用_count()查看它是否等于1,以了解我的应用程序的所有其他部分何时都处理完数据

我提出这个问题的另一个原因是,共享指针上的boost文档建议不要对生产代码使用“use_count”


编辑-
我没有说的是,当我们需要一个新的foo时,我们将扫描foo指针向量,寻找当前未使用的foo,并在下一轮处理中使用该foo。这就是为什么我认为引用计数器为1是一种安全的方法,可以确保这个特定的foo对象不再被使用。

我建议,与其尝试使用共享的使用计数来跟踪,不如实现自己的使用计数。这样,您就可以完全控制这一点,而不是像您正确地建议的那样,使用共享的ptr,因为它不被推荐。您还可以预先设置自己的计数器,以允许您知道需要对数据执行操作的线程数,而不是依赖于在开始时初始化它们来获取结构副本。

如果您想知道使用计数是否为1,请使用
unique()
成员函数。

我想说,你的应用程序应该有一些方法,可以消除应用程序其他部分对Foo的所有引用,并且应该使用该方法,而不是检查
use\u count()
。此外,如果
use\u count()
大于1,您的程序会做什么?您不应该依靠
shared\u ptr
的特性来消除所有引用,您的应用程序体系结构应该能够消除引用。作为从向量中删除它之前的最后一个检查,您可以
断言(unique())
来验证它是否真的被释放了。

我的直接反应(我承认,这只是个问题)是,听起来您好像在试图获得某种池分配器的效果。您最好重载
运算符new
运算符delete
,以便更直接地获得所需的效果。有了这样的功能,您可以像正常情况一样使用
shared_ptr
,其他需要延迟的工作将在该类的
operator delete
中处理

这就留下了一个更基本的问题:你到底想用这个来完成什么?从内存管理的角度来看,一个常见的愿望是一次为大量对象分配内存,并且在整个块为空之后,立即释放整个块。如果你想按这个顺序做一些事情,那么通过重载
new
delete
几乎肯定比通过玩
shared\u ptr
use\u count
更容易完成

编辑:根据您的评论,为类重载
new
delete
听起来是正确的做法。如果有的话,集成到现有代码中可能会更容易;事实上,您通常可以完全透明地执行此操作

分配器的总体思路与您在编辑的问题中概述的基本相同:拥有一个跟踪自由对象的结构(位图和链表都很常见)。当
new
需要分配一个对象时,它可以扫描位向量或查看自由对象链接列表的头部,并返回其地址

这是链表可以很好地工作的一种情况——您(通常)不必担心内存使用,因为您将链接存储在空闲对象中,并且您(实际上)不必遍历列表,因为当您需要分配对象时,您只需抓取列表上的第一项


<>这类事情对于小对象特别常见,所以你可能想看看现代C++设计章节关于它的小对象分配器(以及Andrei Alexandrescu从那时起的一篇文章或两篇关于他如何做那种事情的新想法)。还有Boost::pool分配器,通常至少有点类似。

我认为您可以使用
shared\u ptr
的自定义deleter功能在发布最后一个副本时调用特定的函数。这样,您就根本不用
use\u count

您需要在
向量
中保存除
共享的ptr
副本以外的其他内容,以便
共享的ptr
仅跟踪未完成的处理


Boost在
共享文档中有一个文件。

您的代码是多线程的吗?如果答案是肯定的,这将改变答案。是的,有3到6个线程在处理数据。你已经很好地总结了我的问题。我们正试图将其用作对象池,以便从中获得下一个免费对象。无论我们做什么,我们还必须看看我们是否能够将其改造到我们现有的代码库以及我们的新应用程序中。