reinterpret_cast 详解
reinterpret_cast 是 C++ 中最危险、最强大,也最接近底层硬件的类型转换操作符。它的名字“reinterpret”(重新解释)已经揭示了其本质:把内存中的二进制比特位,强行当作另一种类型来解读,而不做任何数值转换或运行时检查。
语法
cpp
reinterpret_cast<new_type>(expression)
其中 new_type 必须是指针、引用、算术类型(整数/浮点数)、函数指针等。
主要用途
-
指针与指针之间:将 T* 转为 U*(两者类型毫无关联),例如 int* 转为 float*。
-
指针与整数之间:将指针转为足够大的整数(uintptr_t),或反之,用于存储/传递地址。
-
函数指针之间:将不同签名的函数指针互相转换(极度危险,极少使用)。
核心规则与极大风险(必须牢记)
不做任何检查:全部由程序员保证正确性,编译器完全信任你。
严格别名规则(Strict Aliasing):通过 reinterpret_cast 转换后解引用(即读写对象),通常属于未定义行为(UB),除非:
-
目标类型是 char / unsigned char / std::byte(用于查看对象内存表示)。
-
或者最终把指针转回原来的类型。
对齐问题:如果目标类型对齐要求更严格,直接解引用可能导致 CPU 崩溃(总线错误)。
可移植性:不同平台(大小端、指针大小)结果可能完全不同。
何时应该使用
-
底层系统编程、驱动开发、网络封包拆解。
-
实现类型擦除或序列化(临时存储为字节流)。
-
与 C 库交互时,遇到不透明的 void* 句柄。
#include <iostream>
#include <iomanip> // for std::setw, std::setfill
#include <cstdint> // for uintptr_t
int main() {
int num = 0x12345678; // 十六进制,便于观察字节
// ———- 场景1:将 int 指针重新解释为字节指针 ———-
// 这是标准允许的,因为 char/unsigned char 可以检查任何对象的表示
unsigned char* bytes = reinterpret_cast<unsigned char*>(&num);
std::cout << "整数 0x12345678 在内存中的字节(从低地址到高地址): ";
for (size_t i = 0; i < sizeof(num); ++i) {
// 以两位十六进制输出每个字节
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(bytes[i]) << " ";
}
std::cout << std::endl;
// 运行说明:在 x86 小端机器上输出 "78 56 34 12"(低字节在前)
// 在大端机器上则会输出 "12 34 56 78"
// ———- 场景2:指针 <-> 整数(标准保证安全) ———-
void* ptr = # // 任意指针
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); // 指针转为整数(存地址值)
std::cout << "指针地址转为整数: 0x" << std::hex << addr << std::endl;
// 整数再转回原始类型的指针(安全,因为指向的对象仍然存在且有效)
int* recovered = reinterpret_cast<int*>(addr);
std::cout << "转回指针后读取的值: " << *recovered << std::dec << std::endl; // 输出 0x12345678
return 0;
}
网硕互联帮助中心



评论前必须登录!
注册