由于我的菜鸟名声,我无法回复此 Thread ,具体是接受的答案:
I never used boost::intrusive smart pointers, but if you would use shared_ptr smart pointers, you could use weak_ptr objects for your cache.
Those weak_ptr pointers do not count as a reference when the system decides to free their memory, but can be used to retrieve a shared_ptr as long as the object has not been deleted yet.
这当然是一个直观的想法,但是,C++ 标准不支持weak_ptrs 的比较,因此它不能用作关联容器的键。这可以通过为weak_ptrs实现一个比较运算符来规避:
template<class Ty1, class Ty2>
bool operator<(
const weak_ptr<Ty1>& _Left,
const weak_ptr<Ty2>& _Right
);
这个解决方案的问题在于
(1) 比较运算符必须为每个比较获取所有权(即从weak_ptr refs 创建shared_ptrs)
(2)当最后一个管理资源的shared_ptr被销毁时,weak_ptr并没有从缓存中删除,而是一个过期的weak_ptr被保存在缓存中。
对于 (2),我们可以提供一个自定义析构函数 (DeleteThread),但是,这将需要再次从要删除的 T* 创建一个 weak_ptr,然后可以使用它从缓存。
我的问题是,是否有更好的使用智能指针的缓存方法(我使用的是 VC100 编译器,没有提升),还是我根本不明白?
干杯,丹尼尔
最佳答案
您想要实现的可能解决方案可能是
假设 T
是你的对象和shared_ptr<T>
是你的共享指针
- 只有普通的
T*
在您的缓存中。 - 为您的
shared_ptr<T>
提供自定义删除器 - 让您的自定义删除器删除您的
T*
从缓存中删除。
这样缓存不会增加您的 shared_ptr<T>
的引用计数但在 ref 计数达到 0 时会收到通知。
struct Obj{};
struct Deleter
{
std::set<Obj*>& mSet;
Deleter( std::set<Obj*>& setIn )
: mSet(setIn) {}
void operator()( Obj* pToDelete )
{
mSet.erase( pToDelete );
delete pToDelete;
}
};
int main ()
{
std::set< Obj* > mySet;
Deleter d(mySet);
std::shared_ptr<Obj> obj1 = std::shared_ptr<Obj>( new Obj() , d );
mySet.insert( obj1.get() );
std::shared_ptr<Obj> obj2 = std::shared_ptr<Obj>( new Obj() , d );
mySet.insert( obj2.get() );
//Here set should have two elements
obj1 = 0;
//Here set will only have one element
return 42;
}
关于c++ - 当没有更多引用时,如何从缓存中删除(非侵入式)智能指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8446376/