Boost logo

Boost Users :

From: Jean-François Brouillet (verec_at_[hidden])
Date: 2005-05-19 16:46:36


> So setting add_ref to false does not suggest that
> intrusive_ptr_add_ref will not be called?

Oh yes it does. What is does NOT suggest is that
~intrusive_ptr WILL call intrusive_ptr_release() MO MATTER WHAT

That is this asymmetry which is cause of confusion, and for
which I've still got a hard time figuring out a valid use case
that would require this rather odd behavior.

Let's assume we had intrusive_ptr2 with _exactly_ the same
interface as intrusive_ptr but with the added behavior that
if the constructor is called with "false", then the destructor
does NOT call intrusive_ptr_release.

What is the name you would choose for the "addRef" parameter?
"managed" ? Or maybe, simply "addRef" after all, since you
would _assume_ by virtue of the symmetric behaviour of a destructor
w.r.t a constructor, that whatever the constructor does, the
destructor un-does it, and whatever the constructor does NOT do,
the destructor does NOT un-do.

Why break the assumption held at the core of C++, that constructors
and destructors have a mirror behavior w.r.t each other?

> We already went over this. You can package 'this' in a shared_ptr<>
> in a member function by using enable_shared_from_this<>. You can
> package 'this ' in a shared_ptr<> in the constructor by using a
> null_deleter if the shared_ptr<> will not be used outside the class,
> so it can't outlive it.

I'm surely dense, but the problem I had what that each shared_ptr
initially derived from``this'' (call this "A") consitutes the root
of a graph for ALL subsequent shared_ptr derived from "A" (through
assignment or copy construction), but each such root has its OWN IDEA
about the reference count, which doesn't match the idea of any other
such root.

While I'm open to use "null_deleter" and all that zoo for *implemeting*
a full-proof envelope, it is just not my intention to expose any
"null_deleter", "enable_shared_from_this" and other whatnots to client
code.

Inside Object, and in the surrounding infrastructure, I'm prepared
to do whatever it takes. Outside Object, only envelopes should be
visible, both syntactically and semantically. And that envelope MUST
behave the way a standard T * does in C++ in the presence of Boehm's
GC (minus its idiosyncratic problems)

> You can't package 'this' in a shared_ptr<> in the constructor and pass
> it to someone else; you can do this in a static create() function.
> However, ...

Another nail in the shared_ptr coffin :(

> ... if you want to stay true to the original Java code, GC may be the
> only choice. Few smart pointers can cope with user code of the form
>
> xxx_ptr p1( new X );
> xxx_ptr p2( new X );
>
> p1->set_callback( p2 );
> p2->set_callback( p1 );

That's why I'm very grateful you provided me with an URL to cyclic_ptr!

I'm still wrapping my head around the code, but from the outset, this is
the closest I've come to my requirements, so far.

> Even if you take care of every 'this', you can't stop people
> from creatin g circular dependencies.

cyclic_ptr is precisely supposed to handle this case.

> C++ code is usually designed from the ground up to avoid these
> scenarios

I don't have that luxury :-(

Many thanks for your time.

--
JFB

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