Ответ
В C++ для безопасности и ясности кода вместо C-style приведения (type)value рекомендуется использовать четыре оператора явного приведения:
-
static_cast<NewType>(expression)- Назначение: Основное «безопасное» приведение для семантически совместимых типов.
- Проверка: На этапе компиляции.
-
Примеры:
double d = 3.14159; int i = static_cast<int>(d); // Преобразование числа void* ptr = malloc(100); char* charPtr = static_cast<char*>(ptr); // Приведение void* к конкретному типу указателя class Base {}; class Derived : public Base {}; Derived* d = new Derived(); Base* b = static_cast<Base*>(d); // Восходящее приведение в иерархии
-
dynamic_cast<NewType>(expression)- Назначение: Приведение указателей/ссылок в полиморфной иерархии классов (где есть виртуальные функции) с проверкой во время выполнения (RTTI).
- Проверка: Во время выполнения. Возвращает
nullptr(для указателей) или бросаетstd::bad_cast(для ссылок) при неудаче. -
Пример:
class Base { public: virtual ~Base() {} }; class Derived : public Base {}; Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b); // Успешно Base* b2 = new Base(); Derived* d2 = dynamic_cast<Derived*>(b2); // d2 будет nullptr
-
const_cast<NewType>(expression)- Назначение: Единственный способ добавить или убрать квалификаторы
constиvolatile. - Внимание: Применять крайне осторожно. Изменение
constобъекта, изначально объявленного как константный, ведет к неопределенному поведению. -
Пример (легальный случай — снятие const с указателя на не-const данные):
void print(char* str) { /*...*/ } const char* message = "Hello"; // print(message); // Ошибка компиляции print(const_cast<char*>(message)); // Возможно, если функция не меняет данные
- Назначение: Единственный способ добавить или убрать квалификаторы
-
reinterpret_cast<NewType>(expression)- Назначение: Низкоуровневое, опасное приведение, которое интерпретирует битовое представление одного типа как другой. Зависит от платформы.
- Использование: Крайне редко, например, для взаимодействия с железом или при сериализации.
- Пример:
int ipAddress = 0xC0A80101; // 192.168.1.1 char* bytes = reinterpret_cast<char*>(&ipAddress); // Теперь bytes указывает на память, содержащую ipAddress
Правило: Всегда предпочитайте static_cast, dynamic_cast, const_cast или reinterpret_cast C-style cast. Они четко указывают намерение и ограничивают круг возможных преобразований, делая код безопаснее.