Why is dynamic_cast evil or not ? Should I use dynamic_cast in this case?

This is EXACTLY the wrong place to use dynamic_cast. You should be using polymorphism. Each of the Animal classes should have a virtual function, say, process and here you should just call animal->process().

class Animal {
    virtual void Process() = 0;
}

class Cat : public Animal {
    void Process() { std::cout << " I am a tiny cat"; }
}

class Bear : public Animal {
    void Process() { std::cout << "I am a big bear"; }
}

void func(Animal * animal) {
    if (animal != nullptr) { animal->Process(); }
}

Other problems.

What if animal is a Dog, but due to a bug animal_type says its a Cat?

There are times when static_cast is necessary, and if possible use it instead of dynamic_cast. Dynamic cast has the additional performance cost that static cast does not. For this, you need to be sure you know the type that is coming in, since static_cast is more unsafe.

At the very least, animal_type should be a member of Animal.


In theory, down-casting should never be necessary. Instead you should adapt the base class to include the necessary virtual method.

In practice, you encounter things such as 3rd party libraries. In this case, modifying the base class is not an option and thus you may be forced into using dynamic_cast...

Back to your example:

class Animal {
public:
    // starts moving toward `p`,
    // throws a `Unreachable` exception if `p` cannot be reached at the moment.
    virtual void moveToward(Point const& p) = 0;
}; // class Animal

And then:

bool move(Animal& animal, Point const& p) {
    try {
        animal.moveToward(p);
        return true;
    } catch (Unreachable const& e) {
        LOG(animal.id() << " cannot reach " << p << ": " << e.what());
    }

    return false;
} // move