Related to Same address, multiple shared_ptr counters, is it forbidden by C++ standard? and myriad other questions around multiple shared_ptr objects pointing to the same object but not sharing the underlying ref count structure.
What happens if the object inherits from “enable_shared_from_this” in the above mentioned question? What does my shared_from_this() return? One with the custom deleter or the one without?
struct B : boost::enable_shared_from_this<B> {
boost::weak_ptr < B > get_weak() {
return shared_from_this();
}
};
void doNothing(B *) {
}
int main() {
B * b0 = new B;
boost::shared_ptr < B > sddb0(b0, doNothing);
boost::weak_ptr < B > swddb0(sddb0->get_weak());
// Does this have a custom deleter???
boost::shared_ptr < B > sddb1 = swddb0.lock();
boost::shared_ptr < B > scdb0(b0);
boost::weak_ptr < B > swcdb0(sddb0->get_weak());
// Does this *not* have a custom deleter???
boost::shared_ptr < B > scdb1 = swcdb0.lock();
}
The deleter is associated with the owned object and will be used to dispose of it when the last owner drops its reference, so all pointers that share ownership of the same object also share the deleter. The deleter is not stored in individual
shared_ptrobjects, it’s stored on the heap along with the reference counts, so shared by all the objects that share the same counts.So let’s looks at your code. First, I had to fix your code as it didn’t even compile as shown. It’s always a good idea to test the code in your question, to avoid wasting people’s time by making them fix typos and add missing headers.
Don’t write this:
The correct way to do that is:
The
enable_shared_from_this<B>base has aweak_ptr<B>member which gets assigned to by theshared_ptrconstructor, so thatweak_ptrshares ownership withsddb0, as does the shared pointer returned byshared_from_this().So the answer to this question is yes:
sddb1shares ownership withsddb0so has the same deleter.You could test that by using
get_deleter, or by writing tostdoutindoNothing, or by usingowner_lessto compare the owners of the pointers.This creates an object that does not share ownership with the existing shared pointers:
boost::shared_ptr < B > scdb0(b0);
The
enable_shared_from_this<B>base’sweak_ptr<B>member gets re-assigned to by the line above, so it shares ownership withscdb0instead ofsddb0. So when you callget_weakafter that point it returns a weak pointer that shares ownership withscdb0and so doesn’t have a custom deleter. Again, you can easily verify that by seeing thatdoNothingisn’t called, or by usingowner_less.