Boost logo

Boost Users :

From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2005-05-22 23:03:16

> Date: Sun, 22 May 2005 00:21:21 +0100
> From: Jean-Fran?ois Brouillet <verec_at_[hidden]>
> Subject: [Boost-users] Re: ~intrusive_ptr bug?
> To: boost-users_at_[hidden]
> Message-ID: <76267242-0F5F-415A-A5ED-D671F4DE420F_at_[hidden]>
> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
> I fail to see the "generality" in the current design. An example where
> it actually makes sense to not "addRef" on ctor but to "remRef" on dtor
> would be most welcome.
> > If you're arguing that the design of intrusive_ptr should be changed,
> I don't have such pretensions. I was only suggesting to *rename* the
> parameter ``addRef'' into something less confusing because of the
> asymmetric behavior.
> Many thanks.
> --

Here's my story:

I wrote my own "AutoRefCountPtr" before seeing boost::intrusive_ptr.
It is almost exactly the same as intrusive_ptr, including the addRef.
Here's why I need the addRef:

I'm using a library (DLL) that only exposes abstract classes (in the h
file). To get a 'real' object/implementation, I call a function to
create an object:


Internally, this creates a Foo_Implementation, but it is returned to
me as a Foo *. Part of Foo's interface is reference counting, via
foo->AddRef() and foo->RemoveRef(). So when I'm done with Foo, I call
RemoveRef. Note, however, that the Foo * returned from CreateFoo is
already addRef'd and ready to go. So I don't need to call AddRef.
   I could (and did for a while) manage my Foo*'s manually, but after
a number of leaks, I gave up and wrote a smart ptr (AutoRefCountPtr)
that would RemoveRef automatically when I was done with the pointer.

So there's your example.

I few other notes:

1. maybe CreateFoo() should have returned a AutoRefCountPtr for me,
instead of a 'naked' Foo *. But this is a bit hard, because CreateFoo
is inside the DLL, and doesn't really want to pass back any 'real'
objects (beside abstract interfaces) because the DLL and the EXE may
be built differently, not at the exact same version, etc.

2. maybe the whole system suffered from a fundamental design flaw, and
is a bad example. That could be, but nonetheless, it was an essential
library, and I didn't really have the option to NOT use it or rewrite
it, so an intrusive_ptr like thing was 'real world' helpful, even if
only to assist in living with a design flaw. (Not that I think there
was a design flaw, but even if there was...)

3. Note that, like intrusive_ptr, my ptr made the initial 'addRef'
optional. It needed to be false when you created the object, but if
Foo * was passed in as a function argument, that function might wrap
it in an intrusive_ptr that DID need to do the initial addref.

4. I called my flag 'addRef'. Is that exactly the same as
intrusive_ptr? Note that this still doesn't mean it is a good name -
I was the *implementor* and it made sense to me, and was very
descriptive for the *implementation*. But maybe it wouldn't make
sense for the client/user (which was also me, in my case :-). I
suspect boost's 'addRef' was also named from an implementation rather
than usage point of view. But I'm still not sure what a better name
would be. Maybe "already_pre_addRefd_thanks' or something like that?
I do sometimes agree with names that are NOT exactly obvious as long
as they are interesting enough that the user is likely to dig a little
deeper to find the meaning. But my co-workers often disagree...

p.s. I originally made my flag a template parameter, partially
because I like this syntax so much:

   if (AutoRefCountPtr<Foo, false> foo = CreateFoo(blah))
 instead of
   if (AutoRefCountPtr foo(CreateFoo(blah), false))
which doesn't always compile, because it confuses the compiler,
   if (AutoRefCountPtr foo = AutoRefCountPtr(CreateFoo(blah), false))
which just isn't as clear as the first way.

The problem with making the flag a template param is that
AutoRefCountPtr<Foo, false> is not the same type as
AutoRefCountPtr<Foo, true>
so assignment, etc is a bit tricky.

Anyone have a good solution to that?


Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at