【问题标题】:Reference counted smart pointer that deletes owned object with ref count greater than zero?删除引用计数大于零的拥有对象的引用计数智能指针?
【发布时间】:2010-11-07 23:05:09
【问题描述】:

我有一个设计,其中对象同时由 2 个队列拥有。有时队列本身可能会被删除。在这种情况下,队列中的所有对象都必须从它们所在的另一个队列中删除并移除。

当前的解决方案让拥有的对象知道两个拥有队列,但这引入了丑陋的耦合。

是否有可以帮助我的智能指针类?构造将使用“新”或现有指针的副本。销毁将删除拥有的资源。访问就像一个weak_ptr,提供指向空值的可能性。

我猜它可能需要一个特定的“销毁”方法,以确保指针的临时副本不会释放资源。

有人知道这样的事吗?

谢谢, 托尼

【问题讨论】:

    标签: c++ boost smart-pointers


    【解决方案1】:

    您希望删除队列中的对象以将其从另一个队列中移除,而不会将其耦合到队列中。

    避免这种耦合的一种方法是将对象标记为已删除,而不是实际删除它。

    • 使用包装对象作为队列的成员。一个逻辑排队的对象有两个包装器对象,每个队列一个。
    • 每个包装器都包含一个 boost::shared_ptr 对象,逻辑上是每个队列的成员。
    • 包装器的析构函数标记逻辑排队的对象为死亡。
    • 从队列中拉出项目时,忽略标记为已死亡的项目。

    【讨论】:

    • 谢谢。这听起来不错,但是如果一个队列死亡并且我们在另一个队列中有“挂起”包装器(并且仍然是实际排队的对象),它们什么时候被删除?我想我们必须删除它们,而不是忽略标记的死项目。
    • 这里的问题是如果一个队列安静但没有被删除。也许队列可以自己定期搜索死对象。
    • 您是否定期从每个队列中拉出项目?如果是这样,上面“何时”问题的答案是“何时将它们从另一个队列中删除”。在第二条评论中,“安静”是什么意思?
    • 抱歉,语言非常不准确。 “安静”是指队列的客户端停止将项目从队列中拉出。如您所见,如果发生这种情况,会导致使用队列访问删除逻辑死对象时出现问题,但队列可以在不弹出的情况下进行垃圾收集。
    • 这听起来很合理,让队列自己处理死对象。如果消费者停止提取物品,队列溢出是否也是您的担忧?
    【解决方案2】:

    一般来说,在存在引用循环的情况下,没有任何可重用的引用计数解决方案。有一些解决方案,但它们要么特定于允许的引用周期模式,要么特定于垃圾收集器。根据您描述问题的方式,您需要能够弄清楚给定队列拥有哪些对象(以便您可以删除队列)以及哪些队列拥有给定对象(以便您可以从所有队列中删除一个对象)。所以你有参考周期。

    为了解决丑陋的耦合问题,我建议让队列包含代理对象,每个代理对象都拥有真实对象并知道哪个队列拥有它。队列方法将使用和更新这些代理对象。

    【讨论】:

    • 感谢您的回答。我用谷歌搜索了“参考周期”。我不相信循环在这里是一个问题,尽管我明白为什么它们会影响一般情况,因此为什么没有一般的解决方案。安迪的回答看起来有点像垃圾收集器,也许这就是要走的路。
    猜你喜欢
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多