Должен ли static_cast <Derived *> (базовый указатель) давать ошибку времени компиляции?

Если static_cast (базовый указатель) дает ошибку времени компиляции?

class A
{
public:
    A()
    {

    }
};

class B : public  A
{
 public:
     B()
     {
     }
};

int main()
{
    A *a=new A();
    B * b=static_cast<B*>(a);   // Compile Error?
}

Ответ 1

Он не может дать ошибку времени компиляции, потому что отношение Base-Derived может существовать во время выполнения в зависимости от адреса вызываемых указателей. static_cast всегда преуспевает, но поднимет undefined -behavior, если вы не нарисуете правильный тип. dynamic_cast может выйти из строя или нет, фактически сообщив вам, пытаетесь ли вы применить правильный тип или нет.

Итак, по-моему, static_cast следует использовать для понижения, только если проект может установить, что такая возможность существует. Хорошим примером этого является CRTP. Поэтому в некоторых ситуациях это логично, но старайтесь избегать этого, поскольку это undefined -behavior.

RTTI не требуется для static_cast, который может сделать его теоретически быстрее, но я буду в любое время торговать a dynamic_cast против поведения undefined, который может вызвать static_cast!

Ответ 2

Он не дает ошибку времени компиляции, потому что приведение может быть очень хорошим, и вы часто делаете это на практике, например:

A* a = new B;
B* b = static_cast<B*>(a); // OK

В вашем коде, что касается компилятора, вы делаете то же самое. Он не может знать, что приведение будет недействительным, поэтому оно позволяет это во время компиляции. Однако во время выполнения вы получите некоторые неприятные ошибки, как только попытаетесь использовать функцию B в экземпляре A.