Boost logo

Boost Users :

From: Jean-François Brouillet (verec_at_[hidden])
Date: 2005-05-15 17:39:23


On 2005-05-15 20:46:56 +0100, "Peter Dimov" <pdimov_at_[hidden]> said:

> 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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net