Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-11-25 14:18:14


From: "Jim Grandy" <jgrandy_at_[hidden]>
> On 11/25/02 10:06 AM, "Peter Dimov" <pdimov_at_[hidden]> wrote:
>
[...]
> >> This would allow one to use this style of code:
> >>
> >> intrusive_ptr<OpaqueRefCountedString> s =
> >> dont_addref(CopyMenuTitle(m));
> >
> > intrusive_ptr<OpaqueRefCountedString> s = CopyMenuTitle(m);
> > s->Release(); // or however it's spelled
> >
> > ?
> >
> Calling Release is semantically correct, but inefficient (in some cases
> prohibitively so), since we're dealing with C API calls made over a
library
> boundary. In particular, Release() is not going to get inlined.

Well, perhaps. If you are worried about addref/release performance, be sure
to write

intrusive_ptr<ORCS> s(dont_addref(CopyMenuTitle(m)));

and not

intrusive_ptr<ORCS> s = dont_addref(CopyMenuTitle(m));

as the latter may result in an extra intrusive_ptr copy, i.e.
addref/release. ;-)

> Additionally, this idiom is so common in certain OS's that a clear
one-line
> solution would be preferable. Perhaps "reuse_ref" would be a better choice
> than "dont_addref"?

OK, here is the one-line solution:

template<class T> intrusive_ptr<T> dont_addref(T * p)
{
    intrusive_ptr<T> pt(p);
    intrusive_ptr_release(p);
    return pt;
}

To expand on that a bit, yes, I considered providing a "no addref"
constructor, and decided against doing so. Constructing an intrusive_ptr
without an addref is indeed a common task when using some C-like interfaces
(COM) but in my experience, once you start using a smart pointer to talk to
these libraries, earlier or later you find yourself wrapping it in a smart
pointer-friendly, C++ style interface, and at that point the "no addref" is
really an implementation detail. The users of _your_ wrapped interface
should never need the "no addref" option.


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