Reputation: 19434
I have a central repository of objects Base
which can produce various things. Base
must keep a pointer to all objects, as a central update method has to iterate through all objects created by the Base
instance. However, if the last handle to an object is destroyed, there is no need to keep it around any more so Base
should get somehow informed that it is ok to delete the object now. Manual deletion of objects should be also possible, which would immediately invalidate all handles. Some code to clarify:
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
Anything ready-to-use out there that I can adopt for this? Performance does not matter too much in this case.
Upvotes: 1
Views: 121
Reputation: 70094
Assume that type of h1
, h2
, h0
is 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();
}
};
Above is pseudo code just to give idea. You can enhance on it if it works. The only difference I have made is to make Delete
a static
. So now instead of,
b->Delete(h1);
You have to call
Delete(b, h1);
This doesn't take care of h2
case. If you are ok with this approach then, we can try adding some logic to that.
Upvotes: 1
Reputation: 10730
Someone has to own these objects. Whoever owns it should hold a shared_ptr. Everyone else should have a weak_ptr. If its not clear who owns it, make a service and only let the service own the object.
Upvotes: 0
Reputation: 477700
How about this: Your class Base
outputs shared_ptr
s through the Make*
functions, but only stores weak_ptr
s internally. The update loop can check whether the weak pointer is still valid and remove it if not.
Your final requirement that deleting the base will also kill existing objects is a bit trickier. You could go through the weak pointers in Base
's destructor and send a self-destruct signal to all live objects, but that wouldn't stop existing shared pointers.
Upvotes: 1