Dynamic casts allow us to transform from a base class to a derived class and perform non-polymorphic actions on it.
Considering the following code:
class Animal {
void breathe();
};
class Feline : public Animal {
void run();
};
int main() {
Animal *p_animal = new Feline;
Feline *p_feline = dynamic_cast<Feline*>(p_animal);
if (p_feline) {
p_feline->run();
}
}
We can cast the animal pointer to a feline pointer using dynamic_cast and call feline specific methods using the resulting pointer. The code to do the casting with smart pointer is just as simple:
std::shared_ptr<Animal> p_animal = std::make_shared<Feline>(Feline();
std::shared_ptr<Feline> p_feline = std::dynamic_pointer_cast<Feline>(p_animal);
p_feline->run();
We can also dynamic cast references but in such a case we can’t check for success as a reference can’t be null. To perform such a check, cast the reference to a pointer.
Feline *p_feline = dynamic_cast<Feline*>(&animal_ref);
A lot of down-casting is usually a sign that the design is wrong and that the functions should be polymorphic is the first place.