Search code examples
c++shared-ptr

How would one specify a custom deleter for a shared_ptr constructed with an aliasing constructor?


How would one specify a custom deleter for a shared_ptr constructed with an aliasing constructor?

struct Bar { 
    // some data that we want to point to
};

struct Foo {
    Bar bar;
};

shared_ptr<Foo> f = make_shared<Foo>(some, args, here);
shared_ptr<Bar> specific_data(f, &f->bar);

// ref count of the object pointed to by f is 2
f.reset();

// the Foo still exists (ref cnt == 1)
// so our Bar pointer is still valid, and we can use it for stuff
some_func_that_takes_bar(specific_data);

How will this line shared_ptr<Bar> specific_data(f, &f->bar); be modified to add a custom deleter?


Solution

  • It doesn't really make sense to add a custom deleter in the construction of the aliasing shared_ptr.

    The deleter is associated with the managed object, not the specific shared_ptr instance that will actually call it. The deleter is stored together with the object in the shared control block.

    So once all aliasing and non-aliasing shared_ptr instances to the shared object are destroyed, the last instance (whether it is aliasing or not) will call the deleter which was associated with the object when it was first put under shared_ptr control.

    So to add a custom deleter for the Foo object, replace std::make_shared:

    auto f = std::shared_ptr<Foo>(new Foo(some, args, here), some_deleter_here);
    

    some_deleter_here will then be called with the Foo pointer as argument, even if the aliasing shared_ptr is the last to be destroyed.

    Note however that if you are using a custom deleter, then you probably are not creating the pointer with a simple call to new. The only correct way to delete an object created with new is to call delete on it, which is what the default deleter already does.