|
Boost : |
From: Ed Brey (brey_at_[hidden])
Date: 2002-07-17 15:43:06
"Peter Dimov" <pdimov_at_[hidden]> wrote in message news:017901c22daa$4bb21f10$1d00a8c0_at_pdimov2...
> >
> > 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?
It's more of a lost opportunity than a problem. Any time the compiler can catch a bug at compile time, you have a good thing. In my example above, the program with intrusive_ptr would compile but not work. Based on what you've written below, I believe we're on the same page here.
> > 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.
> [...]
> 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.
I agree with this. If intrusive_ptr were used only as to represent things like COM objets, the implicit raw-pointer construction is just fine. However, I see an additional opportunity for intrusive_ptr, which is as a more efficient shared_ptr, given a counted_base. (I'm using "counted_base" as shorthand for any counting mechanism embedded within the object.) The more often that intrusive_ptr is used in place of shared_ptr, the more problematic the "use at your own risk" caveat becomes.
Perhaps the best option would be to merge the two. Just as shared_ptr "auto-detects" a counted base and becomes more efficient, would it not be reasonable to take that to the next level so that shared_ptr elides is pointer-to-count member given a counted base? (I'm not sure how to implement this off hand.) Then, aside from accepting raw pointers, there'd be no difference between intrusive_ptr and shared_ptr. Correct?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk