Boost logo

Boost Users :

From: Joseph Thomson (joseph.thomson_at_[hidden])
Date: 2008-04-06 15:40:30


Hi everyone,

Over the past few days I have been trying to integrate Boost smart pointers
into my system, which is basically a manager (ObjectManager) class which
creates, destroys, and keeps track of instances of another class (Object).

The manager keeps a std::map of instances of type shared_ptr. The manager
has a createObject() method which returns a shared_ptr instance to the user,
thus the user becomes an owner of the object, alongside the manager. My
problem arises because I want objects to _always_ be destroyed when the
manager method destroyObject() is called. I realise that part of the reason
to use smart pointers is to prevent data from being deleted while a
reference to it still exists, but I figure they are still worth using just
for the safety aspect.

My specific reasons for wanting the manager to be able to destroy the
objects on command are:

1.) The manager may keep track of the objects, but the objects are used
elsewhere in the system (until their destruction).
2.) I don't want to put the responsibility with the user (me!) to have to
delete all references to the object in order for it to be deleted. Even if
I pass back a weak_ptr, it is likely that the user will store a locked
version of the pointer for convenience.
3.) I am using lua, which has no C-style "delete" command, and handles
object deletion in its own time. Thus, even if all references to the object
have been deleted in lua, the object may not actually be deleted straight
away (unless you invoke deletion by calling collectgarbage(), which is a
very messy solution).

Anyway, I came up with a solution, but am not sure if there is any better or
cleaner way. I am relatively new to smart pointers and the whole idea of
virtual methods, so if I use the wrong terminology I apologise. Here goes:

I have an abstract ObjectInterface class, which outlines all the methods
that the user will access. I then have an Object class, which is of type
ObjectInterface, and implements its abstract methods. The ObjectManager
will, as before, create and store a map of shared_ptr references. However,
instead of returning a shared_ptr to the user, the
ObjectManager::createObject() method now creates a shared_ptr<ObjectHandle>
which it returns to the user. ObjectManager doesn't store a reference to
the handle, so the user is the sole owner of that. ObjectHandle (I'm not
sure this is the correct use of the term "Handle"?) is also of type
ObjectInterface, but in its constructor it takes a shared_ptr reference from
the ObjectManager, which it stores internally as a weak_ptr (so that
ObjectManager remains the sole owner of Object). It implements the
ObjectInterface methods by forwarding calls from the user to the Object, but
only if the weak_ptr hasn't expired. I am also storing a raw pointer to the
Object in ObjectHandle, so that it doesn't have to call shared_ptr<>::lock()
every time it needs to forward a call; I think this is reasonable to do
since I never copy the pointer, and certainly won't delete it.

Attached is a fully working example that I have tried to make as concise and
clear as possible. Maybe my solution is the best one and my question seems
stupid, or maybe there is a far simpler way and my solution seems stupid,
but either way I am asking because I am unsure about this kind of thing in
general.

Thanks very much for any help in advance!

Joe

http://www.nabble.com/file/p16528658/smart_ptr_example.cpp
smart_ptr_example.cpp

-- 
View this message in context: http://www.nabble.com/-smart_ptr--Sole-ownership-of-shared_ptr--tp16528658p16528658.html
Sent from the Boost - Users mailing list archive at Nabble.com.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net