Не используйте приведение типов в стиле С

Приведение типов в стиле С может выполнять сразу несколько преобразований, которые фактически не контролируются компилятором, могут приводить к UB и вызывать ошибки во время выполнения. C++ приведения более безопасны и контролируемы.

Плохой пример:

double d = 3.14;
int* p = (int*)&d;  // C-style cast: компилятор пропустит, но это UB!

В C++ такой код потребует явного reinterpret_cast, что уже сигнализирует об опасности:

int* p = reinterpret_cast<int*>(&d);  // Явно говорит: "это рискованно!"
  • static_cast используется для безопасного преобразования между числовыми типами, от наследника к родителю (обратное преобразование небезопасно, но возможно), между связанными типами указателей (например, от void к int и обратно). static_cast не бесплатен и создает определенный код преобразований.
  • const_cast используется для безопасного снятия или добавления const/volatile модификаторов. При этом сам объект не изменяется, меняется только его "видимость" для компилятора
  • dynamic_cast - используется с полиморфными объектами (у которых есть виртуальные функции) во время выполнения, для безопасного преобразования от родителя к наследнику. Работает только с указателями и ссылками. Может бросать исключение std::bad_cast. Преобразование dynamic_cast тяжелое и его лучше избегать в высоконагруженных системах.
  • reinterpret_cast используется для приведения между типами, которые не связаны стандартными преобразованиями, а значит является небезопасным и необходимо его по-возможности избегать.

Для безопасного приведения std::shared_ptr используйте аналоги: std::static_pointer_cast, std::const_pointer_cast, std::dynamic_pointer_cast и std::reinterpret_pointer_cast.