Ответ
static_cast — это оператор явного преобразования типов, проверяемый на этапе компиляции. Он используется для "разумных" и относительно безопасных преобразований, где логика преобразования ясна из контекста кода.
Основные сценарии применения:
-
Преобразование между числовыми типами (например,
intвfloat,enumвint).int i = 42; double d = static_cast<double>(i); // Явное указание на сужение/расширение -
Явное преобразование вниз по иерархии наследования (downcast), когда программист уверен в типе объекта. Если уверенности нет, следует использовать
dynamic_castс проверкой.class Base { virtual ~Base() = default; }; class Derived : public Base { /*...*/ }; Base* basePtr = new Derived; // Безопасно только если мы ЗНАЕМ, что basePtr указывает на Derived Derived* derivedPtr = static_cast<Derived*>(basePtr); -
*Преобразование из `void`** обратно в исходный тип указателя, когда тип известен.
int value = 10; void* genericPtr = &value; int* intPtr = static_cast<int*>(genericPtr); // Восстановление типа -
Подавление предупреждений компилятора о неиспользуемых переменных или параметрах (альтернатива
(void)var).[[maybe_unused]] int unused = 5; // Предпочтительный способ (C++17) static_cast<void>(unused); // Альтернативный способ -
Вызов explicit-конструкторов или преобразующих операторов.
class MyString { public: explicit MyString(const char*); // explicit-конструктор }; MyString s = static_cast<MyString>("hello"); // Ок, явный вызов
Чего НЕ делает static_cast:
- Не выполняет проверку типов во время выполнения (это
dynamic_cast). - Не преобразует между указателями на несвязанные типы (это
reinterpret_cast). - Не снимает константность или волатильность (это
const_cast).
Ответ 18+ 🔞
А, ну это же про static_cast, классика жанра! Слушай, представь себе такую ситуацию: ты пишешь код, и компилятор начинает ныть, как баба на сенокосе: «Ой, типы не совпадают, ой, неявное преобразование». И тут ты такой: «Да похуй, я сам всё контролирую!» — и вмандюриваешь static_cast.
Это, блядь, как взять молоток и аккуратно, с чувством, долбануть по гвоздю, чтобы он вошёл ровно. Не как reinterpret_cast, который просто берёт и забивает гвоздь утюгом через окно, ебать копать. static_cast — он для разумных, вменяемых преобразований, которые компилятор в принципе понимает, но требует твоего явного «да, я в курсе, делай».
Где его впендюрить можно и нужно:
-
Числа туда-сюда. С
intнаdouble, сenumнаint— обычное дело. Просто говоришь компилятору: «Чувак, я вижу, что тут может потеряться точность или ещё какая хуйня, но я сознательно на это иду, делай».int i = 42; double d = static_cast<double>(i); // Всё чётко, я сказал «преобразуй» -
Вниз по иерархии, когда ты уверен как в себе. Есть базовый класс, а ты точно знаешь, что в этом указателе сидит объект наследника.
dynamic_castс проверкой — это как идти к тёще в гости с цветами и тортом. Аstatic_cast— это когда ты уже двадцать лет женат и просто кричишь из прихожей: «Мама, я дома!». Рисковано? Да. Но если не ошибешься — быстро и без церемоний.Derived* derivedPtr = static_cast<Derived*>(basePtr); // Только если ты на 146% уверен! -
*Из `void
обратно.** Это как отдать чемодан без ручки в камеру хранения (void*), а потом по номерку (static_cast`) забрать, зная, что внутри именно твои трусы и носки, а не чей-то динамит.int* intPtr = static_cast<int*>(genericPtr); // Восстанавливаю тип, я же помню, что туда клал! -
Заткнуть компилятор. Он иногда бздит на неиспользуемые переменные. Можно сделать вид, что использовал, прикинувшись шлангом.
static_cast<void>(unusedVariable); // Да иди ты, компилятор, всё равно переменная нужна! -
Вызвать
explicit-конструктор. Это когда класс такой хитрожопый и говорит: «Я изconst char*создамсь, но только если ты явно попросишь, не надейся на авось».MyString s = static_cast<MyString>("hello"); // Ну я попросил, доволен?
А чего он НЕ умеет, этот static_cast?
- Проверять типы в рантайме — это не его собачье дело, для этого есть
dynamic_cast, который бегает с RTTI и всё вынюхивает. - Преобразовывать левое в правое — типа
int*вSomeClass*(если они не в одной иерархии). Это уже территорияreinterpret_cast, там ад и Израиль. - Сдирать
const— хочешь снять константность? Этоconst_cast, но будь готов, что программа может накрыться медным тазом, если объект на самом деле в read-only памяти. Доверия к такому коду — ноль ебать.
Короче, static_cast — это твой основной инструмент для явных, осознанных преобразований. Не reinterpret_cast, где можно получить манда с ушами, а нормальный, цивилизованный способ сказать компилятору: «Я тут подумал, и давай сделаем вот так».