TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #256 3.51K
reinterpret_cast

Исходя из имени этого оператора, он вводится для узкой специализации: "переосмыслить" значение, т.е. представить его в другом виде. Его используют для приведение несовместных типов: «указатель к объекту», «указатель к указателю». Из живого примера 1:
double  *pointer_f64 = new double(42);
int64_t *pointer_i64 = reinterpret_cast<int64_t *>(pointer_f64);
int64_t  value_i64   = reinterpret_cast<int64_t> (pointer_i64);
int32_t *pointer_i32 = reinterpret_cast<int32_t *>(value_i64);

Приводя типы таким оператором, мы никак его не преобразуем с точки зрения памяти. Но теперь, обращаясь к тем же байтам, как к другому типу, с ними можно работать иначе.

Где же нам такое может понадобиться? Если не брать в пример какой-нибудь зловещий хакинг чисел с плавающей запятой на уровне битов, то в основном, при работе с сырой памятью. Например, при записи и чтении данных в файл:
void save(const double &hp)
{
file.write(reinterpret_cast<const uint8_t*>(&hp), sizeof(hp));
}

void load(double &hp)
{
file.read(reinterpret_cast<uint8_t*>(&hp), sizeof(hp));
}

Наверняка вы знаете, что числа с плавающей точкой совершенно иначе представляются в системе, в отличии от целочисленных значений в двоичном виде. Это позволяет нам оперировать ну ооочень большими и маленькими десятичные значениями, выходящими за рамки возможного для целочисленных типов.

Давайте попробуем увидеть, как расставлены биты в типе double в живом примере 2. При решении этой задачи можно воспользоваться готовой стандартной структурой std::bitset(unsigned long long) для распечатки битов. Однако, есть нюанс! Тип данных double можно привести к соразмерному unsigned long long двумя разными способами, которые дают совершенно разный результат.

Так, static_cast отбрасывает дробную часть и преобразует к целочисленному значению, а reinterpret_cast просто иначе интерпретирует расставленные биты. В следствие этого из 42.0 мы получаем не 42, а какое-то другое и явно отличное от исходного число: 4631107791820423168. Очень похоже на то, как мы иногда в шутку пытаемся услышать слова родного языка в иностранных песнях.

Однако, с точки зрения поставленной задачи, именно оно нам и нужно — тип unsigned long long просто выступает в роли «грузового контейнера» для транспортировки 64 битов, которые std::bitset потом благополучно печатает в консоль.

#cppcore
  • 👍 19
  • 🔥 5
  • ⚡ 1
  • ❤ 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →