具有自动清除功能的中央注册表中对象的句柄

Handles to objects in central registry with automated cleanup

本文关键字:对象 句柄 注册表 功能 清除      更新时间:2023-10-16

我有一个中央对象存储库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

有什么现成的我可以采用的吗?在这种情况下,性能并不太重要。

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

您的最后一个要求,即删除基础也将杀死现有对象,是有点棘手的。您可以遍历Base的析构函数中的弱指针,并向所有活动对象发送自毁信号,但这不会阻止现有的共享指针。

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的情况。如果您对这种方法满意,那么我们可以尝试添加一些逻辑。

必须有人拥有这些对象。无论谁拥有它,都应该持有一个shared_ptr。每个人都应该有一个weak_ptr。如果不清楚谁拥有这个对象,就创建一个服务,并且只让服务拥有这个对象。