将void指针转换为特定类型指针时,哪个转换符号更好,static_cast或reinterpret_cast?

Sid*_*ang 37 c++ casting

可能重复:
在将void*转换为任何内容时,我应该使用static_cast还是reinterpret_cast

在这个程序中,我有一个void *参数,并希望将其转换为特定类型.但我不知道使用哪种"铸造符号".无论是static_cast还是reinterpret_cast工作.哪一个更好?标准C++推荐哪一个?

typedef struct
{
    int a;
}A, *PA;

int foo(void* a)                // the real type of a is A*
{
    A* pA = static_cast<A*>(a); // or A* pA = reinterpret_cast<A*>(a);?
    return pA->a;
}
Run Code Online (Sandbox Code Playgroud)

这是

A* pA = static_cast<A*>(a);
Run Code Online (Sandbox Code Playgroud)

要么

A* pA = reinterpret_cast<A*>(a);
Run Code Online (Sandbox Code Playgroud)

更合适吗?

tem*_*def 51

static_cast是更合适的用于将void*一些其他类型的指针.

static_cast当两种类型之间存在自然,直观的转换时,它是一种选择,它不一定能保证在运行时工作.例如,您可以使用static_cast将基类指针转换为派生类指针,这是一种在某些情况下有意义但在运行时才能验证的转换.类似地,您可以使用static_castinta 转换为a char,这是明确定义的但在执行时可能会导致精度损失.

reinterpret_cast另一方面,是一个铸造操作员,旨在进行从根本上说不安全或不便携的转换.例如,你可以使用reinterpret_cast从转换void *int,如果你的系统中恰好有这将正常工作sizeof (void*)sizeof (int).你也可以使用reinterpret_cast一个转换float*到一个int*或反之亦然,这是因为特定的表示特定于平台的floatS和ints的不能保证什么共同点彼此.

简而言之,如果您发现自己正在进行转换,其中转换具有逻辑意义,但可能不一定在运行时成功,请避免reinterpret_cast. static_cast如果你有一些预先知道演员表会在运行时工作,并与编译器通信,那么这是一个很好的选择."我知道这可能不起作用,但至少它是有道理的,我有理由相信它会正确在运行时做正确的事." 然后,编译器可以检查转换是否在相关类型之间,如果不是这种情况则报告编译时错误.使用reinterpret_cast指针转换执行此操作会完全绕过编译时安全检查.

在某些情况下,您可能希望使用a dynamic_cast而不是a static_cast,但这些情况主要涉及类层次结构中的强制类型转换(并且很少)直接关注void*.

至于哪一个是规范首选,既没有被过度提及为"正确的使用"(或者至少,我不记得其中一个被这样提到.)但是,我认为规范要你用完static_castreinterpret_cast.例如,当使用C风格的演员表时,如

A* ptr = (A*) myVoidPointer;
Run Code Online (Sandbox Code Playgroud)

尝试的转换操作符的顺序总是尝试使用a static_cast之前的a reinterpret_cast,这是您想要的行为,因为reinterpret_cast不保证是可移植的.

  • 澄清:作者在这里所说的"`static_cast` ...不一定能保证在运行时工作"是,"你的程序可能会在以后崩溃." 如果你从一个基类型到一个派生类型`static_cast`,它将**在运行时"工作"(即你不会**得到异常或`NULL`指针),但结果可能是如果涉及多重继承,则指向错误的内存位置.(有关详细信息,请参阅[此答案](http://stackoverflow.com/a/7789468/266704).)只有`dynamic_cast`才会执行运行时检查(使用RTTI),如果强制转换无效,则会正常失败. (2认同)

归档时间:

查看次数:

51513 次

最近记录:

14 年,6 月 前