I have this function which adds any class that derives from Object to a container.
template<class T> void registerObject(T& object) {
auto sp = std::shared_ptr<T>(&object, [](T*){});
std::shared_ptr<Object> op = std::static_pointer_cast<Object>(sp);
objects_.push_back(op);
}
What happens in the static_pointer_cast that makes the custom delete method still valid for the new pointer?
I ask because doesn’t the lambda evaluate to taking the derived type? But then the casted pointer will pass a Object* to that lambda? So isn’t some “upcasting” happening when the custom delete is called? Which I thought was impossible because you can’t guarantee that the base type is the derived type?
Here’s how a
boost::shared_ptrworks:Each instance (in your code) has a pointer to a shared single control block for the pointee.
At least conceptually it also has a raw pointer to the pointee, of the type implied by this instance. Due to the type this raw pointer can be adjusted, not the same bitpattern as the original pointee pointer.
The control block contains the original raw pointee pointer, a reference count, and the original deleter func. The deleter func is called (when and if it is) with the original raw pointee pointer as argument.
When you cast you only affect the new
shared_ptrinstance, not the control block that it points to. So, the information needed for deletion is not affected at all. Even though the instance’s (conceptual) typed pointee pointer can be affected.