I have a class hierarchy and in it B is derived from A like this:
class A : public std::enable_shared_from_this<A>
{
};
class B : public A
{
void f()
{
// the code below compiles
std::shared_ptr<B> copyOfThis = std::static_pointer_cast<B>(shared_from_this());
// the code below does not
std::shared_ptr<B> copyOfThis = static_cast<std::shared_ptr<B>>(std::make_shared<A>(shared_from_this()));
}
};
So actually I want to understand why I cannot use static_castto cast a shared_ptr of parent class to child class when it is actually contains this of child.
EDIT: Look at this question: Polymorphic smart pointer usage Here I have asked why shared pointer of child can be casted on shared pointer of parent. And the answer is there is a template constructor. See details in the question. So why this constructor does not help for casting even if there is no relationship between shared_ptr<A> and shared_ptr<B>.
You can't cast shared_ptr<A> to shared_ptr<B> because there is no inheritance relationship between the types. For the same reason you can't cast vector<A> to vector<B>.
Instantiating a class template with related types does not make the template instantiations also related.
The shared_ptr<T>(const shared_ptr<Y>&) constructor doesn't help because it is only usable if Y* is implicitly convertible to T*, i.e. it is there to support the same pointer conversions as would happen implicitly, like B* to A*, not A* to B*.
What you can do is this:
shared_ptr<A> thisA = shared_from_this();
shared_ptr<B> thisB(thisA, static_cast<B*>(thisA.get()));
This creates a shared_ptr<B> that shares ownership with thisA, and holds the pointer static_cast<B*>(thisA.get())
That is exactly what static_pointer_cast<B>(thisA) does, but the aliasing constructor used above was added to shared_ptr later, so didn't exist when static_pointer_cast was invented, and it is also much less clear what it is doing. static_pointer_cast is much more expressive. If you want to perform a static cast on the pointer types, use static_pointer_cast.
Long story short: std::shared_ptr<A> is not a parent of std::shared_ptr<B>. That is the whole point of static_pointer_cast existence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With