I am looking at the shared_ptr implementation in the following post. One question that is not entirely clear to me is, why in addition to the pointer stored with T*
type in shared_ptr class itself, author also needs to store the second copy of the managed object's pointer with its concrete type in the control block (i.e. U* p;
in auximpl
). I understand why we need this for custom deleter, but not for actual pointer. It looks like this complies with the requirements of the standard, when I read control block description in cppreference page. Author made the following comment about this
"this is needed to properly manage all the cases of T being a base for whatever U having multiple T in the derivation hierarchy"
but I still can't come up with an example of when this will really be required. Can someone please demonstrate it with an example?
Thank you, -Grigor
CodePudding user response:
One case is when using shared_ptr
's alias capability.
Create a shared_ptr
using an object's member but the control block is the same and thus the reference count.
class holder : public std::enable_shared_from_this<holder>
{
int member;
public:
std::shared_ptr<int> get_member() {
return std::shared_ptr<int>(shared_from_this(), &member);
}
};
std::shared_ptr<int> foo()
{
auto ptr = std::make_shared<holder>();
return ptr->get_member();
}
the object created in the make_shared
call won't be freed until the object returned from foo's reference count goes to 0.