Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-08-27 10:14:31


From: "Douglas Paul Gregor" <gregod_at_[hidden]>
> On Tue, 27 Aug 2002, Peter Dimov wrote:
> > From: "Douglas Gregor" <gregod_at_[hidden]>
> > > >
> > > > Also, get_pointer for weak_ptr was deliberately omitted as
dangerous.
> > Why
> > > > do you need it?
> > >
> > > void bar(weak_ptr<X> x)
> > > {
> > > some_signal.connect(bind(&X::foo, x));
> > > }
> > >
> > > We need to get to the X* for the base-pointer conversion to trackable*
> > (for
> > > the automatic signal/slot disconnections).
> >
> > But that's exactly why I didn't add get_pointer for weak_ptr.
bind(&X::foo,
> > x) is only valid when get_pointer is present; but there is no reason to
bind
> > a member function to a weak pointer, because you can't detect from
within
> > the member function whether "this" is zero (meaning that the weak
pointer
> > has been zeroed.)
>
> But in this case, we _can_ detect when "this" is zero if it is a trackable
> object.

Not necessarily. x may already refer to a dead object, or it might refer to
a live object but this object may die a split second later, before connect()
has a chance to visit it.

> "this" is zero only when the object it refers to has been
> destroyed; however, the destruction of that object will disconnect the
> signal/slot connection that contains the weak_ptr, so a null "this"
> pointer won't ever show up in a slot call.

You have enabled bind(&X::foo, x) where x is a weak_ptr because, in one
specific situation that you are interested in, you think that this is not an
error. :-)

The right way to use a weak_ptr is to never access get(), directly or
indirectly. It seems that I have to remove it altogether, and declare that a
weak pointer is not a pointer.

void bar(weak_ptr<X> x)
{
    if(shared_ptr<X> tmp = make_shared(x))
    {
        some_signal.connect(bind(&X::foo, tmp.get()));
        // tmp.get() is still valid here
    }
    // tmp.get() may now be invalid, but the signal would have disconnected
already
}

> Interestingly, this means that
> shared_ptr generally shouldn't be used within slots because the slot might
> be the only thing keeping both ends of the connection alive. (I smell a
> FAQ entry...)

Yes. An owning pointer in the slot means that the object will never die, and
this in turn means that you don't need to track the object... unless I'm
missing something.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk