通过自动清理处理中央注册表中的对象

时间:2011-07-20 14:43:37

标签: c++

我有一个对象Base的中央存储库,它可以生成各种各样的东西。 Base必须保留指向所有对象的指针,因为中央更新方法必须遍历Base实例创建的所有对象。但是,如果对象的最后一个句柄被销毁,则不需要再保留它,因此Base应该以某种方式通知现在可以删除该对象。也应该手动删除对象,这将立即使所有句柄无效。一些代码澄清:

Base* b = new Base;
auto h0 = b->MakeFoo ();
auto h1 = h0;
b->Delete (h0);
// h1 is invalid here
{
  auto h2 = b->MakeFoo ();
}
// Base::Delete (h2) was called, as the last reference to it died
// shared_ptr/weak_ptr won't work here, as there would be still one
// reference in Base
auto h3 = b->MakeFoo ();
delete b;
// h3 is invalid here, hence shared_ptr is not enough
// weak_ptr would work here

我可以采用哪些随时可以使用的东西?在这种情况下,性能并不重要。

3 个答案:

答案 0 :(得分:1)

如何:您的班级Base通过shared_ptr函数输出Make*,但仅在内部存储weak_ptr。更新循环可以检查弱指针是否仍然有效,如果没有则将其删除。

删除基础的最终要求也会杀死现有对象有点棘手。您可以浏览Base的析构函数中的弱指针,并向所有活动对象发送自毁信号,但这不会停止现有的共享指针。

答案 1 :(得分:1)

假设h1h2h0的类型为TYPE*

class Base {
// ...
  map<TYPE*, int> t_HandleMap;
public:
  TYPE* MakeFoo ()
  {
    TYPE* p = new TYPE;
    t_HandleMap[p] = 0;
    return p;
  }

  static void Delete (Base *&pB, TYPE *pH)
  {
    t_HandleMap.erase(pH);
    if(t_Handlemap.empty())
    {
      delete pB; pB = 0;
    }
  }
  ~Base ()
  {
    for(<iterate through map>)
      delete <pHandle>;
    t_HandleMap.clear();
  }
};

上面是伪代码只是为了提供想法。如果有效,你可以加强它。我唯一的区别是让Delete成为static。所以现在代替,

b->Delete(h1);

你必须致电

Delete(b, h1);

这不会照顾h2个案。如果您对此方法没有问题,我们可以尝试添加一些逻辑。

答案 2 :(得分:0)

有人必须拥有这些物品。谁拥有它应该持有shared_ptr。其他人都应该有一个weak_ptr。如果不清楚谁拥有它,请提供服务,只让服务拥有该对象。

相关问题