
Date: Sun, 22 May 2005 00:21:21 +0100 From: Jean-Fran?ois Brouillet <verec@mac.com> Subject: [Boost-users] Re: ~intrusive_ptr bug? To: boost-users@lists.boost.org Message-ID: <76267242-0F5F-415A-A5ED-D671F4DE420F@mac.com> 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. -- JFB
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: CreateFoo(fooparams,..); 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, or 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? Tony
participants (1)
-
Gottlob Frege