Boost logo

Boost :

From: Scott McMurray ([hidden])
Date: 2008-08-28 17:52:40

On Thu, Aug 28, 2008 at 13:05, Felipe Magno de Almeida
<felipe.m.almeida_at_[hidden]> wrote:
> On Thu, Aug 28, 2008 at 1:54 PM, Scott McMurray <[hidden]> wrote:
>> Custom deleters also make it quite awkward to handle properly.
> Why?
>> Since it would require that only one pointer holds it, it seems like
>> the correct way to do it is to use unique_ptr instead, which enforces
>> that invariant.
> True. But it might be useful when you need to comply with
> an interface.

Because you have to store the pointer and the deleter somewhere
anyways in order to clean it up properly after a hypothetical release.
 Since the shared_ptr is already doing that for you, why wouldn't you
just keep it around until you're done with it?

If you're receiving arbitrary shared_ptrs, then it's quite possible
that unique will never be true, so you can't be certain you can ever
release it in the first place.

If you're just doing it to conform to an interface, then you don't
know if the library is holding a copy, so you can't rely on being able
to release it.

If you have control over the whole stack, then you can use a unique_ptr instead.

Or if you really want, there's already sufficient infrastructure to do
cleanup externally to the shared_ptr. Just use a nop deleter and
something like this:
T *release_assuming_nop_deleter(shared_ptr<T> &sp) {
    T *p = sp.get();
    weak_ptr<T> wp = sp;
    if (shared_ptr<T> nsp = wp.lock()) {
        sp = nsp;
        return 0;
    } else {
        return p;

I think that it shouldn't be in the code, though, or it's just asking
for people to do delete sp.release(); (though likely less directly
than that) without realizing that it's wrong. At the very least, if
it absolutely had to be added, release() would need to return a
pair<T*, boost::function<void(void*)> > (or similar).

Boost list run by bdawes at, gregod at, cpdaniel at, john at