Ответ
В C++ существует четыре основных вида явного приведения типов, каждый со своей семантикой и областью применения:
-
static_cast— базовое приведение, проверяемое на этапе компиляции. Используется для преобразований между числовыми типами, указателями вверх/вниз по иерархии наследования (без проверки на этапе выполнения) и для явного вызова конструкторов/операторов преобразования.double d = 3.14; int i = static_cast<int>(d); // Преобразование double в int Base* basePtr = new Derived(); Derived* derivedPtr = static_cast<Derived*>(basePtr); // Вниз по иерархии (опасно, если basePtr не указывает на Derived) -
dynamic_cast— предназначен для безопасного приведения вниз или вбок по иерархии полиморфных типов (классов с виртуальными функциями). Проверка осуществляется во время выполнения (RTTI). При неудаче для указателей возвращаетnullptr, для ссылок — исключениеstd::bad_cast.Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b); // Успешно, если b действительно указывает на Derived if (d) { // Работаем с d } -
const_cast— используется для добавления или удаления квалификаторовconstиvolatile. Основное применение — работа с устаревшим кодом, где функция принимает неконстантный указатель, хотя данные не изменяются.void legacyFunction(char* str); const char* greeting = "Hello"; // legacyFunction(greeting); // Ошибка компиляции legacyFunction(const_cast<char*>(greeting)); // Опасно, если legacyFunction модифицирует данные -
reinterpret_cast— низкоуровневое приведение, которое интерпретирует битовое представление объекта одного типа как объект другого типа. Крайне опасно и зависит от платформы (порядок байт, выравнивание). Используется, например, для приведения указателя к целочисленному типу или между несвязанными типами указателей.int* ip = new int(0x41424344); char* cp = reinterpret_cast<char*>(ip); // Интерпретируем память int как массив char // cp[0] может быть 'D' (ASCII 0x44) или 'A' (0x41) в зависимости от endianness
C-style cast (type)value в C++ пытается применить комбинацию static_cast, const_cast и reinterpret_cast и может быть неявным. Его использование не рекомендуется, так как оно менее безопасно и затрудняет поиск мест приведения в коде.