On 2005-05-15 20:46:56 +0100, "Peter Dimov"
You can do this with shared_ptr, but not with intrusive_ptr. ;-)
That's extremely funny ... I moved away from shared_ptr to intrusive_ptr because I needed the envelope to use the same reference count no matter how they were created. Now, I would need to go back to shared_ptr, precisely because the reference counts are separate ... Let's recap: I need an envelope for ``this'' when embedding it into itself. - some kind of weak, non ref-counted pointer would do. I need an envelope for ``this'' when passing it as argument to some library that expects an envelope, not a body. - all such envelopes need to share the same ref-count otherwise I will leak. In one of my intrusive_ptr attempt, I tried ... setCallback(TaskDone(this, false)) ; ... In the hope that the "false" argument (matching; ``addRef'' in the template) would note trigger a call to intrusive_ptr_add_ref. But for some reason that still escapes me, this somehow played harsh with the construction leading to a "pure virtual method call" on the defining "start", whereas passing "true" (that is, using the default value) led to proper behavior in this regard. Unless I can find an appropriate "cyclic" implementation, I'm kind of OKish to accept both a strong and a weak envelope, as would have been the case with intrusive_ptr had I succeeded in getting the ``false'' argument to behave as advertised :-[
class C: private I { shared_ptr<I> myI;
void i(); // ...
C( C const & ); C& operator=( C const & );
public:
C(): myI( this, null_deleter() ) { }
void setI( shared_ptr<I> const & i ) { myI = i; } };
A null_deleter works here because you know that the internal I and the shared_ptr member have the same lifetime, that of C.
Well, a "null_deleter" for a smart_ptr should be semantically equivalent to an "addRef" set to false in an intrusive_ptr, right? I guess I get what the problem was now: intrusive_ptr(T * p, bool add_ref = true): p_(p) { if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_); } Here the refCount is not incremented if addRef is false. However: ~intrusive_ptr() { if(p_ != 0) intrusive_ptr_release(p_); } has no way to know whether addRef was called or not at construction time. This explains probably why this was wreaking-havoc my tests ... Thanks for keeping this thread alive :-) -- Do your users a favor: give them Style: http://www.uiwithstyle.org