C ++类型转换。 static_cast何时成功并且reinterpret_cast会导致问题?

时间:2017-06-30 11:58:45

标签: c++ casting

我理解reinterpret_cast是一种从一种类型到另一种类型的演员,(直觉上)是一种演员,在某些情况下可以成功并且在没有危险演员的情况下有意义。同时,static_cast是一个表示不安全转换的转换,可能会将一个值的位重新解释为另一个值的位。

有人可以描述代码编译,强制转换以及reinterpret_cast不会导致问题的方案,但{{1}}会出现问题吗?

3 个答案:

答案 0 :(得分:21)

这样做:

#include <iostream>
using namespace std;

struct C{int n;};
struct A{int n;};
struct B : A, C{};

int main()
{
    B b;
    B* pb = &b;
    cout << static_cast<C*>(pb) << "\n";
    cout << reinterpret_cast<C*>(pb);
}

注意两个地址的差异。

我在这里构建了一些多重继承,并在基类中放置了一个显式成员,以避免将空基类的可能优化大小调整为零。

请参阅https://ideone.com/QLvBku

答案 1 :(得分:16)

最简单的这种情况是reinterpret_cast<void*>(NULL),它可能会产生一个非空指针。

相比之下,static_cast<void*>(NULL)是安全的,因为它需要产生一个空指针。

为什么呢? NULL是一个等于0的整数常量。static_cast要求将0转换为适当的空指针,但reinterpret_cast不具有相同的要求。如果空指针的内部表示与整数零的内部表示相同,则结果将不同。这种类型的破坏最有可能发生在具有分段寻址的架构上。

答案 2 :(得分:9)

其中一种情况是多重继承 - static_cast调整地址(因此,强制转换后基础对象指针的地址可能与派生对象地址不同,指向正确的基类项目)。

reinterpret_cast不进行任何地址调整,因此转换为基类可能使用错误的地址(即始终返回派生对象的地址不变)。