Search code examples
c++shared-ptrdowncastvirtual-inheritance

How to downcast a shared_ptr in the case of virtual inheritance?


Suppose I have a class C, inheriting from B, itself virtually inheriting from A:

class A {};
class B : virtual public A {};
class C : public B {};

Now suppose I have a std::shared_ptr<A> managing an object which I know for sure is of some class inheriting B (e.g., of class C), and I even happen to have it available as a raw B pointer, in a way equivalent to the minimal example below:

B * pb = new C;
std::shared_ptr<A> spa(pb);

Now I want to downcast the std::shared_ptr<A> to a std::shared_ptr<B>. I can't use static_pointer_cast because the inheritance is virtual. I could use dynamic_pointer_cast but it seems an overkill given that I already have the object available as a raw B pointer.

Is the following code the appropriate way to achieve my goal?

std::shared_ptr<B> spb(spa, pb);

It seems that yes, but I'd like some confirmation from someone who knows better (I never had to use the aliasing constructor before).


Solution

  • Is the following code the appropriate way to achieve my goal?

    Yes. In both cases (your alternative and dynamic_pointer_cast), you get a shared_ptr who's operator-> will return a reference to a B. And in both cases, it is the object A which will have delete called upon it when all references are destroyed. In all ways they will behave the same.

    Which also means that if you don't define a virtual destructor in A, then in both cases, your code will break upon the deletion of A.

    That being said, there's nothing "overkill" about using a dynamic_pointer_cast in this circumstance.