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_cast
to 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