Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-04-03 07:03:29

Marcin Kaliciñski wrote:
> Hi Everybody,
> Smart pointers in boost work on a principle of preventing object
> destruction while references to it exist anywhere in the system. It
> causes that whoever owns a boost::shared_ptr to some object, has
> power to decide for how long will that object live. This is
> "ownership".
> In some situations it would be more convenient if object itself
> decided when to die (owned itself?), and notified all reference
> holders about this fact, so that they not try to use it any more.

You can do this with shared_ptr/weak_ptr.

> A real-life example from a computer game code. There are C++ objects
> representing tanks on the battlefield. When tank gets hit, it
> explodes and ceases to exist. The nice, straighforward way to do it
> is to write "delete this;" in C++. All references to deleted tank
> which are held by other tanks (for example those currently aiming at
> it, or following it), will be immediately updated to NULL, provided
> that they are live_ptrs: [...]

You can make the object own itself by adding a shared_ptr member to it that
holds a self-reference (this_). The self-destruction is accomplished with
this_.reset(). All weak_ptr instances will "expire". Or you can use a null
deleter if you want to delete the object explicitly and not use shared_ptr
to manage its lifetime:

but this solution has a drawback that I mention below.

In practice, my tanks are usually owned by a container (vector<
shared_ptr<Tank> > in the simplest case), because I need to enumerate them.

> template<class T>
> class live_ptr
> {
> // Member functions closely resembling those of shared_ptr
> // When object pointed to is deleted, this pointer resets its value
> to NULL
> };

The problem with providing such an interface is lack of reentrancy and
thread safety. Consider this code:

live_ptr<X> px;

if( px != 0 )

If after the px != 0 check the object is deleted by a different thread,
px->f() will crash. This can also happen in some complex single threaded
code. weak_ptr::lock is designed to prevent this from happening by giving
you a shared_ptr to the object which keeps it alive.

> class Tank;
> void live_ptr_test()
> {
> Tank *tank = new Tank;
> live_ptr<Tank> p(tank); // not ownership, but a "live" reference
> delete tank;
> assert(p == 0);
> }

Your live_ptr<> requires support from Tank, right?

Boost list run by bdawes at, gregod at, cpdaniel at, john at