Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2002-01-17 18:37:49


From: "Stewart, Robert" <stewart_at_[hidden]>
> From: Greg Colvin [SMTP:gcolvin_at_[hidden]]
> >
> > From: "Stewart, Robert" <stewart_at_[hidden]>
> > > > From: Peter Dimov [SMTP:pdimov_at_[hidden]]
> > > >
> > > > As for release(), I think that it needs to be dropped.
> > >
> > > I recently created a special-purpose smart pointer that releases the ref
> > > count of something relying on a C API. I wanted to write my functions
> that
> > > return such pointers to return smart pointer objects to ensure that the
> ref
> > > count was decreased even if I simply ignored the return value of such
> > > functions. However, when returning to the calling C API, I needed to
> turn
> > > over the raw pointer in the return value, relinquishing ownership of it.
> To
> > > do that, I call release() on my smart pointer class (which, based upon
> > > Andrei's insight, should be a non-member function).
> > >
> > > If I were using a Boost smart pointer without support for release(), how
> > > would I relinquish ownership()? That is, how do I tell the Boost smart
> > > pointer to not "deallocate" the pointer it holds, without release()?
> >
> > If I understand you, then I don't see why you need release().
> > I imagine your code looks like this:
> >
> > extern "C" T* entry_point(T* p) {
> >
> > special_smart_ptr<T> wrapped_p(p);
> >
> > do_stuff_with(wrapped_p);
> >
> > assert(wrapped_p.unique());
> >
> > return p;
> > }
>
> Actually, it's like this:
>
> extern "C"
> T * f(stuff)
> {
> special_smart_ptr<T> wrapped(foo(/* some arguments */));
> // do work with wrapped
> return wrapped.release();
> }
>
> where foo() looks like this:
>
> special_smart_ptr<T>
> foo(/* some parameters */)
> {
> special_smart_ptr<T> result(/* create a T * in some way */);
> // do work with result, if appropriate
> return result;
> }
>
> foo() allocates a T *, according to the rules of the API I'm using, which
> requires managing the reference count hidden behind that T *, which is
> opaque. Therefore, since foo() allocates, it needs to ensure that the caller
> knows to release that allocation, so it returns a special_smart_ptr<T> that
> will decrement the reference count automatically unless the caller takes
> ownership in some way.
>
> Because f() calls foo(), it doesn't have access to the T * except through
> "wrapped." However, when f() returns to the API, the API expects to manage
> the reference count of the returned value, so "wrapped" shouldn't do it.
> Therefore, f() calls special_smart_ptr::release() on "wrapped."
>
> Does this make more sense now? How else would I do this, if not with
> release()?

It make sense now, thanks -- you must have release().


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