2

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).

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Boris Dalstein
  • 7,015
  • 4
  • 30
  • 59

1 Answers1

3

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thx! Yes, `A` does have a virtual destructor (like all classes in this inheritance hierarchy). By "overkill", I meant that the overhead of using RTTI seems superfluous in this scenario where I don't need it. – Boris Dalstein Feb 25 '16 at 06:17