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