66

I have two classes A and B, B inherits from A.

If I have a shared_ptr<A> object which I know is really a B subtype, how can I perform a dynamic cast to access the API of B (bearing in mind my object is shared_ptr, not just A?

3 Answers 3

111

If you just want to call a function from B you can use one of these:

std::shared_ptr<A> ap = ...; dynamic_cast<B&>(*ap).b_function(); if (B* bp = dynamic_cast<B*>(ap.get()) { ... } 

In case you actually want to get a std::shared_ptr<B> from the std::shared_ptr<A>, you can use use

std::shared_ptr<B> bp = std::dynamic_pointer_cast<B>(ap); 
Sign up to request clarification or add additional context in comments.

4 Comments

dynamic_cast<B&>(*ap).b_function(); if you are doing this, what is the point of the dynamic_cast. You don't check the result anyway, you would just use static_cast here. I think only the if(B* bp = ... and the dynamic_pointer_cast are correct here.
@FantasticMrFox: a static_cast<B*>(a) can only be used if a was obtained from an implicit conversion from a B*. Of the conversion was from a further derived type or from a sibling class in a scenario involving multiple inheritance the dynamic_cast has defined behavior while the static_cast has not.
dynamic_pointer_cast was exactly what I was looking for (as opposed to dynamic_cast)
@FantasticMrFox You don't need to check the result of the dynamic_cast on reference types... how/what would you check? The specified behavior of dynamic_cast is to throw a std::bad_cast exception when casting references would fail.
26

use dynamic_pointer_cast

example copied from above link

// static_pointer_cast example #include <iostream> #include <memory> struct A { static const char* static_type; const char* dynamic_type; A() { dynamic_type = static_type; } }; struct B: A { static const char* static_type; B() { dynamic_type = static_type; } }; const char* A::static_type = "class A"; const char* B::static_type = "class B"; int main () { std::shared_ptr<A> foo; std::shared_ptr<B> bar; bar = std::make_shared<B>(); foo = std::dynamic_pointer_cast<A>(bar); std::cout << "foo's static type: " << foo->static_type << '\n'; std::cout << "foo's dynamic type: " << foo->dynamic_type << '\n'; std::cout << "bar's static type: " << bar->static_type << '\n'; std::cout << "bar's dynamic type: " << bar->dynamic_type << '\n'; return 0; } 

output

foo's static type: class A foo's dynamic type: class B bar's static type: class B bar's dynamic type: class B 

2 Comments

That example doesn't even need any cast.
Bryan, I cannot plus one you enough for this answer. Thank you.
2

Probably the nicest way would be to use the standard functions for casting a shared_ptr

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.