Отличие динамической проверки типов от статической?
 я возможно не так задал вопрос. хотелось бы узнать, почему компилятор не может все проверить на этапе компиляции. зачем еще добавлять динамическую проверку? class Object {
public:
virtual ~Object() {}
};
class Weapon : public Object {
public:
virtual ~Weapon() {}
};
class Player : public Object {
public:
virtual ~Player() {}
};

void handleObject(Object* object) {
  // What is object? Is it weapon or player?
};

// ....

Object* object = rand() % 100 > 50 ? new Weapon() : new Player();
handleObject(object);
Т.к. не все проверки можно сделать во время компиляции. Компилятор не знает, объект какого типа будет приводиться к какому, ведь по факту, используя интерфейс можно передать любой оъект-наследник. И тут есть два варианта: привести типы небезопасно, но быстро, или надёжно, но медленнее. 
Помимо этого, есть ещё некоторые примеры использования static_cast: https://en.cppreference.com/w/cpp/language/static_cast