Because of my noob reputation, I cannot reply to this Thread, in specific the accepted answer:
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.
This is certainly an intuitive idea, however, the C++ standard does not support comparison of weak_ptrs, so it cannot be used as key for associative containers. This could be circumvented by implementing a comparison operator for weak_ptrs:
template<class Ty1, class Ty2>
bool operator<(
const weak_ptr<Ty1>& _Left,
const weak_ptr<Ty2>& _Right
);
The problem with this solution is that
(1) the comparison operator has to obtain ownership for every comparison (i.e. creating shared_ptrs from the weak_ptr refs)
(2) the weak_ptr is not erased from the cache when the last shared_ptr that manages the resource is destroyed, but an expired weak_ptr is kept in the cache.
For (2), we could provide a custom destructor (DeleteThread), however, this would require again to create a weak_ptr from the T* that is to delete, which can then be used to erase the weak_ptr from the cache.
My question would be if there is any better approach to a cache using smart pointers (I am using the VC100 compiler, no boost), or do I simply not get it?
Cheers, Daniel
A possible solution for what you want to achieve might be
Lets say T
is your object and shared_ptr<T>
is your shared ptr
T*
in your cache.shared_ptr<T>
T*
from the cache upon delete.This way the cache doesn't increase the ref count of your shared_ptr<T>
but is notified when the ref count reaches 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With