2

我在整个应用程序中使用 Boost/shared_ptr 指针。当对对象的最后一个引用被释放时,shared_ptr 将为我删除该对象。应用程序中的对象订阅应用程序中心位置的事件,类似于观察者/订阅者模式。

在对象析构函数中,对象将从订阅列表中取消订阅。订阅列表本质上只是一个list<weak_ptr<MyObject> >. 我想做的是与此类似的事情:

Type::~Type()
{
  Subscriptions::Instance()->Remove(shared_from_this());
}

我的问题是不能在析构函数中调用 shared_from_this ,所以上面的代码会抛出异常。

在我的旧实现中,订阅列表只是一个指针列表,然后它就起作用了。但我想改用weak_ptr 引用来降低我通过手动内存管理搞砸内存的风险。

由于我依赖 shared_ptr 来执行对象删除,因此我的代码中没有一个地方可以逻辑地调用 Unsubscribe。

关于在这种情况下该怎么做的任何想法?

4

2 回答 2

1
  1. 您可以通过 Subscription 实例销毁对象,然后它会自动删除指针。
  2. 你可以忘记从订阅中删除它们——weak_ptr 无论如何都不能被锁定,然后你可以删除它们。
  3. 您可以为每个对象分配一个唯一 ID,然后通过唯一 ID 而不是 shared_ptr 删除
  4. 您可以将普通指针传递给 Remove 而不是共享指针——它将用作“ID”。
于 2009-12-18T20:36:55.023 回答
0

我的问题是shared_from_this不能在析构函数中调用,所以上面的代码会抛出异常。

它将抛出异常,因为根据定义,它在析构函数中已过期。

那你到底想要什么?“过期”的共享指针?只需创建一个空的共享指针。

还是过期的弱指针?

也许如果您注意到“问题”没有shared_from_this抛出(这是一种症状),但所有所有者在那个时候本质上已经被重置或销毁并且弱指针已过期并且相当于一个空的默认创建的弱指针(*),所以你只应该传递一个默认初始化的弱指针。

无论哪种方式(使用弱指针或拥有指针)也Subscriptions::Instance()->Remove(weak_OR_owning_pointer)没有任何意义,因为您无法将弱指针与任何东西进行比较,您只能尝试锁定它(然后进行比较)。

所以你可以删除过期的弱指针。的论点Remove是无用的。

(*) 或者你有一个非常严重的双重错误,即被销毁对象的双重所有权!

于 2018-12-13T01:55:28.583 回答