Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-07-17 10:54:53


From: "Ed Brey" <brey_at_[hidden]>
> "Peter Dimov" <pdimov_at_[hidden]> wrote in message
news:009a01c22d95$6eff7e50$1d00a8c0_at_pdimov2...
> >
> > Yes. intrusive_ptr<> can be safely constructed from a raw pointer that
is
> > already being managed by another intrusive_ptr<>. This makes the
implicit
> > conversion less dangerous. It's still possible to pass a pointer to a
> > stack-allocated object, of course; this is not intrusive_ptr's problem,
> > though. The object is expected to behave appropriately when it's use
count
> > drops to zero. An 'auto' or 'static' intrusive-counted object should
ignore
> > addref/release's.
>
> The danger isn't limited to auto or static objects. It applies to any
object that isn't currently being handled by a supported smart pointer. For
example, consider something like this:
>
> void helper(intrusive_ptr<T> x);
>
> void fn(T& x) {
> foo(&x);
> }
>
> The scenario is that there is some helper function that takes x by
intrusive pointer. The poor sap who is writing fn forgets this and thinks
that helper is taking x by raw pointer. With shared_ptr, the computer
catches his bug (probably a serious logic error, otherwise helper would be
taking T by reference). With intrusive_ptr, this program compiles fine.
<

Why is this a problem?

> This danger applies equally well to shared_ptr and intrusive_ptr, so I
ponder the question of why they don't follow the same strategy. The biggest
difference I see is that intrusive_ptr requires the counted_base (or
equivalent). So the argument for intrusive_ptr being looser is that the
user is less likely to mismanage an object that he went through the trouble
of deriving from counted_base. However, I'm not so sure this is sound. For
example, counted_base could be applied to a class whose objects are
sometimes shared on the heap and sometimes not shared, residing on the
stack.
<

This is what is dangerous, and not the implicit constructor. intrusive_ptr<>
assumes that the object encapsulates the knowledge of how to reference-count
_and_ destroy itself. A stack-allocated object should know to not call
'delete this' on itself.

It is possible to ignore this and reuse the same class for both
heap-allocated objects managed by intrusive_ptr and stack-allocated,
unmanaged objects. At your own risk.

[...]

> One point that might help clarify things is a statement on the intent of
intrusive_ptr. I see it largely as a leaner alternative to shared_ptr,
useful when you always have a counted_base (or equivalent). Is there any
more to it?
<

intrusive_ptr is a generic intrusively-counted pointer, with the associated
performance implications; it can be constructed from a raw pointer (such as
'this'), and it can be used to manipulate COM objects.


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