我有一个对象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
我可以采用哪些随时可以使用的东西?在这种情况下,性能并不重要。
答案 0 :(得分:1)
如何:您的班级Base
通过shared_ptr
函数输出Make*
,但仅在内部存储weak_ptr
。更新循环可以检查弱指针是否仍然有效,如果没有则将其删除。
删除基础的最终要求也会杀死现有对象有点棘手。您可以浏览Base
的析构函数中的弱指针,并向所有活动对象发送自毁信号,但这不会停止现有的共享指针。
答案 1 :(得分:1)
假设h1
,h2
,h0
的类型为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。如果不清楚谁拥有它,请提供服务,只让服务拥有该对象。