static_cast和reinterpret_cast有什么区别?

71

可能是重复问题:
何时应该使用 static_cast、dynamic_cast 和 reinterpret_cast?

我在C++中使用了一个C函数,其中以void类型参数传递的结构体直接存储了相同的结构体类型。

例如,在C中。

void getdata(void *data){
    Testitem *ti=data;//Testitem is of struct type.
}

在C++中我使用static_cast来做同样的事情:

void foo::getdata(void *data){
    Testitem *ti = static_cast<Testitem*>(data);
}

当我使用reinterpret_cast时,它执行相同的操作,将结构体强制转换。

当我使用Testitem *it=(Testitem *)data;时,也是执行相同的操作。 但是,使用这三种方法如何影响结构体。


那个线程讨论了何时使用它。我想知道在使用这三个东西时,与那种结构有什么不同,而我还忘记了dynamic_cast。简单地说,我想知道结构如何受到影响。 - HariHaraSudhan
结构不受影响(除非在数值类型之间进行强制转换)。 - Jim Balter
使用static_castreinterpret_castvoid*转换时得到的结果相同:https://dev59.com/GMHqa4cB1Zd3GeqPuzZY#68137312。 - anton_rh
1个回答

145
static_cast是一种从一种类型到另一种类型的转换,它(直观地)是一种在没有危险转换的情况下可能成功并且有意义的转换。例如,您可以使用static_castvoid*转换为int*,因为void*实际上可能指向int*,或者将int转换为char,因为这样的转换是有意义的。但是,您不能将int*静态转换为double*,因为只有在int*已经被修改为指向double*时,此转换才有意义。 reinterpret_cast是一种表示不安全转换的转换,它可能会重新解释一个值的位作为另一个值的位。例如,使用reinterpret_castint*转换为double*是合法的,尽管结果未指定。同样,使用reinterpret_castint转换为void*是完全合法的,尽管不安全。 static_castreinterpret_cast都无法从某些东西中删除const。您不能使用这两个转换将const int*转换为int*。对此,您将使用const_cast
形式为(T)的C样式转换被定义为尝试进行static_cast(如果可能),如果这样做不起作用,则退回到reinterpret_cast。如果绝对必须,它还将应用const_cast
通常,您应始终优先使用static_cast进行安全转换。如果意外尝试进行未定义的转换,则编译器将报告错误。只有在您真正更改计算机中某些位的解释时才使用reinterpret_cast,如果愿意冒险进行reinterpret_cast,则使用C样式转换。在您的情况下,您应该使用static_cast,因为从void*的下转换在某些情况下是明确定义的。

1
也可以这样写 double pi = 3.1415; int ipi = static_cast<int>(pi); 但是在链接的情况下,必须使用 reinterpret_cast double* pi = 3.1415; int* ipi = reinterpret_cast<int*>(pi); - Sergey Luchko
仍然非常有帮助的答案!我正在编写自定义分配器,并且一直在使用dynamic_cast来在uintptr_tvoid*之间进行转换。 - alexpanter
无论是static_cast还是reinterpret_cast都不能移除const。直接使用是正确的,但被动使用则不正确。看看这个例子:const int n = 9; const int* p = &n; int* i = reinterpret_cast<int*>(reinterpret_cast<unsigned>(p)); 这是针对32位平台的,在64位上,将unsigned改为unsigned long long或者对两者都使用uintptr_t - Iman Abdollahzadeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接