我最近了解到C++标准包含"严格的别名规则",禁止通过不同类型的变量引用同一内存位置。
然而,该标准确实允许char
类型合法地别名任何其他类型。这是否意味着reinterpret_cast
在法律上只能用于转换为类型char *
或char &
?
我相信严格的别名允许在继承层次结构中的类型之间进行强制转换,但我认为这些情况倾向于使用dynamic_cast<>?
感谢
reinterpret_cast
有许多不同的用途。cpprreference页面列出了11种不同的情况。
我猜您只是在询问情况5和6:将T *
强制转换为U *
,将T
强制转换为U &
。
在这些情况下,只要不存在对齐冲突,铸造是合法的。只有在读取或写入结果表达式时才会出现严格的混叠问题。
你在第一段中对严格混叠规则的总结过于简单化了,通常U
有几种法律类型。同一个cppreference页面提供了一个带项目符号的案例列表;您可以在C++标准草案中阅读该规则的确切文本。
reinterpret_cast
还有其他有用的用途。
指向整数类型的指针
是的,有时会希望将指针的值存储在整数类型中。
使用C++样式的强制转换实现这一点的唯一方法是使用reinterpret_cast
。
示例:
auto pointerValue = reinterpret_cast<std::uintptr_t>(pointer);
将对象存储在原始内存块中
有时您希望将数据存储在堆栈上,但稍后会对其进行初始化。使用动态分配和指针不会使用堆栈。std::aligned_storage
作为原始的、对齐的存储器块做得很好。
struct MyStruct {
int n;
std::string s;
};
// allocated on automatic storage
std::aligned_storage<sizeof(MyStruct), alignof(MyStruct)>::type storage;
// actually initialize the object
new (&storage) MyStruct;
// using the object
reinterpret_cast<MyStruct*>(&storage)->n = 42;
我确信还有很多其他用途我不知道,但这些是我已经使用过的。
您还可以使用repret_cast将指针类型强制转换为整数类型:
char* ptr = /* ... */
uintptr_t ptrInt = reinterpret_cast<uintptr_t>(ptr);
您返回的特定整数值不能跨平台移植,但这是一个安全且定义良好的操作。