Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 1999-12-31 00:08:15


From: Dave Abrahams <abrahams_at_[hidden]>
> Greg wrote that I wrote:
> >> The user then specializes boost::deallocator<T> for her own type when it
> >> needs special treatment (yes, this means you need to wrap ints and other
> >> basic types in a struct unless you'll have only one way to deallocate ints.
> >> so what?)
> >
> > If you can do this on per-type basis, then why not just override
> > operator delete for that type?
>
> Simple answer: the type might not be a pointer.

Oh. I thought you said you'd have to wrap basic types in a struct anyway?

> I assumed your motivation for the virtual function proposal was to be able
> to manage non-memory resources, but the more I look at it, the less sense it
> makes. What do you get when you dereference a smart pointer which isn't
> holding a T*? It's oxymoronic. Maybe just moronic ;)
>
> So why _do_ you want to use virtual functions to customize deallocation?

I think you answer this question below.

> >> Then you get fancy with the empty base optimization to store a deallocator
> >> object somewhere in the smart pointer. This avoids all virtual function
> >> overhead.
> >>
> >> If you don't wnat to get all fancy-like, you can construct the deallocator
> >> on-the-fly at deallocation time, or you can just use a template function for
> >> that matter.
> >
> > So I take it you are not buying my concerns about recompiling everything
> > when you change the deallocation specialization?
>
> I guess not, but maybe I haven't considered the scenarios carefully. Perhaps
> you'd like to give some examples?

I gave one example. The issue is that a user of shared_ptr<T> must either
decide up front to use shared_ptr<T,Whatever>, or else parameterize all
uses.

> I can see the value of using polymorphism for deallocation at least in the
> case of shared_ptr: If you keep the deallocator with the count, a shared_ptr
> just becomes a way to maintain the reference count, and there's full
> assignment compatibility between shared_ptrs regardless of how the objects
> they refer to will be deallocated.
>
> template <class T>
> void call_delete(T* p) { delete p; }
>
> template <class T>
> class shared_ptr { ...
> shared_ptr(T* const p, void(*deleter)(T*) = call_delete<T>);
> ...
> };

Bingo!

> The downside is that you pay for an extra function pointer per shared
> object. I don't think we'd want to incur that sort of cost for something
> like auto_ptr, but it may be acceptable for shared_ptr.

You're already paying for the count per object, and if we support weak
pointers you pay for another count, so I think it's no big deal. The
deleter can also serve as a notification that any weak_ptrs are
invalidated. Rather than a pointer to function I'm thinking of imitating
a closure with a reference to a class with a virtual function.

For scoped_ptr I agree this is too heavy-duty.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk