Re: Rewriting clone() to return a boost::shared_ptr ?
Peter Dimov wrote:
kanze wrote:
I tried that, and it didn't work. In my applications, most
of the dynamically allocated objects are entity objects,
with explicitly managed lifetimes. If all I counted on were
boost's smart pointers, I'd need to add some special
function, like dispose, to terminate the object lifetime,
and deal with zombie objects. And once I've added the
necessary logic to ensure that all other concerned objects
are correctly notified when the object's lifetime ends, a
smart pointer doesn't add anything except extra
complications; IMHO, in such cases, it is much easier to
simply do "delete this" in the object function which detects
the condition, and use the destructor to propagate
notification. The equivalent using Boost would probably be
to maintain all of the objects in a collection (generally
necessary anyway), with a shared_ptr in the collection, and
weak_ptr every where else. To me, "delete this" just seems
simpler and more explicit that removing the object from the
collection, and counting on the side effect of removing it
to call delete.
You can do that with shared_ptr if you really like to. Your
objects need to store a shared_ptr to themselves as a member,
and the 'delete this' operation is performed by resetting this
shared_ptr.
I know it's possible, but what does it buy you, except
obfuscation? If I write "delete this", anyone familiar with C++
knows exactly what is going to happen. Resetting a shared_ptr
to trigger delete is IMHO a bit subtle, especially since it
counts on the fact of there not being another shared_ptr to the
same object. When I see shared_ptr, it says "shared" -- I find
it counter-intuitive to use it in cases where, by definition,
there is (or should be) only one owning pointer. Especially,
when there is no other need for that pointer.
You can leak if you somehow lose all pointers to the object,
of course.
I don't see that as an objection, really, since we're not using
the pointer for memory management, but only to obfuscate a
delete this:-).
Seriously, in such cases, there will always be another pointer.
We're talking here about active entity objects, which react to
external events. And for the external event to find the object,
the object must be registered somewhere -- an event handler, a
database (e.g. std::map), etc. The constructor will normally
register it, and the destructor deregister it. In the simplest
cases, at least; in the case of multiple event handlers, it's
possible for the object to deregister from one, and to register
with another, according to its evolving state. And of course,
it's also possible in such cases to end up with an object that
will only be deleted when it processes an event it's not
registered for. Garbage collection with finalizers can help
here -- if you collect such a live object, it's a serious
program error. In the case of a data base (objects identified
by an external id), there are probably cases where keeping a
shared_ptr in the data base makes sense; instead of delete this,
you remove the object from the data base (so no one else can see
it).
One upside is that you can (and will, if you use weak_ptr)
temporarily keep an object alive until you are finished with
it with a local shared_ptr auto variable even if someone
invokes 'delete_this' on it in the meantime (not necessarily
from the same thread).
Temporarily keeping an object alive when it is logically dead
(aka allowing access to a zombie object) is NOT what I would
call an upside. In transactional based systems, you will have
zombie objects within the transaction, in some cases, since you
cannot actually delete until the commit. Typically, however,
the only pointers to those objects should be in the transaction
manager, where no one else can see them, and the transaction
manager handles all of the object lifetime issues -- in a way
more complicated than shared_ptr would normally support.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]