我已经阅读了之前有关使用的reinterpret_cast各种问题,并且我还阅读了C++标准中的相关措辞.本质上,它归结为指针到指针reinterpret_cast操作的结果不能安全地用于除了被回送到原始指针类型之外的任何东西.
然而,在实践中,大多数现实世界的使用reinterpret_cast似乎都是基于(错误的)假设,即a reinterpret_cast与C风格的演员表相同.例如,我见过很多的代码,它使用reinterpret_cast从投char*来unsigned char*的字符集转换程序的目的.这是完全无害的,但严格来说,它不是便携式-有没有保证,一个reinterpret_cast来自char*于unsigned char*当您尝试取消引用不会崩溃您的程序unsigned char*指针.
根据标准,似乎唯一的其他实际用途reinterpret_cast有任何真正的保证,是从指针转换为整数,反之亦然.
然而,在许多情况下,我们希望(并且应该能够)在不同的指针类型之间安全地进行转换.例如:uint16_t*到新的C++ 0x char16_t*,或者实际上是指向与原始类型相同大小/对齐的基本数据类型的任何指针.然而,reinterpret_cast并不保证这应该起作用.
问题:如何安全地在指向相同大小/对齐的基本数据类型的指针之间进行转换,例如char*- > unsigned char*?既然reinterpret_cast似乎并不保证这实际上有效,那么C风格的演员是唯一安全的选择吗?
int i = 1000;
void *p = &i;
int *x = static_cast<int*>(p);
int *y = reinterpret_cast<int*>(p);
Run Code Online (Sandbox Code Playgroud)
哪个演员应该用来转换void*为int*和为什么?
首先,这不是重复的为什么当两个链接的static_cast可以完成它的工作时,我们在C++中有reinterpret_cast?.
我知道我们甚至不能使用两个连锁static_cast来实现这reinterpret_cast一点的情况.但是,在任何情况下我都应该选择两个链接static_cast而不是简单且更具可读性的情况reinterpret_cast吗?
因此,如果您从Void*转换为Type*或从Type*转换为Void*,您应该使用:
void func(void *p)
{
Params *params = static_cast<Params*>(p);
}
Run Code Online (Sandbox Code Playgroud)
要么
void func(void *p)
{
Params *params = reinterpret_cast<Params*>(p);
}
Run Code Online (Sandbox Code Playgroud)
对我来说static_cast似乎更正确,但我看到两者都用于同一目的.此外,转换的方向是否重要.即我还应该使用static_cast:
_beginthread(func,0,static_cast<void*>(params)
Run Code Online (Sandbox Code Playgroud)
我已经阅读了关于C++样式转换的其他问题但是我仍然不确定这个场景的正确方法是什么(我认为它是static_cast)
尽管有很多关于 reinterpret_cast 主题的文章,以及它有多糟糕,但我仍然对避免它的最佳方法感到困惑,尤其是在处理诸如从 fstream 读取和写入之类的函数时。所以,这是我的困境......
假设我们有一个整数数组,我们想用文件中的一些数据填充它。
std::ifstream iFile( ... );
// presume that the type of this array is not a matter of choice
int *a = new int[ 100 ];
Run Code Online (Sandbox Code Playgroud)
我们可以阅读一些不同的演员表:
iFile.read( (char *)a, sizeof( int ) * 100 );
iFile.read( reinterpret_cast< char * >( a ), sizeof( int ) * 100 );
iFile.read( static_cast< char * >( static_cast< void * >( ( a ) ), sizeof( int ) * 100 );
Run Code Online (Sandbox Code Playgroud)
第一个(C 风格)已经过时,我们在 C++ 中引入了新的风格转换,这是有充分理由的。第二个是不可移植的,不提供任何保证。第三个写起来很乏味,破坏了乐趣。
有什么替代方法吗,我应该怎么做?
编辑:
目标是使代码尽可能可移植且符合标准。
可能重复:
当两个链接的static_cast可以完成它的工作时,为什么我们在C++中有reinterpret_cast?
有人建议我不要在指向指针转换的情况下使用reinterpret_cast或const_cast.只应使用dynamic_cast.因为其他演员可能会在将来产生问题.所以我的问题是为什么不能从c ++标准中删除reinterpret_cast或其他危险的演员表.