【转】C++标准转换运算符reinterpret_cast

reinterpret_cast<new_type> (expression)

reinterpret_cast运算符是用来处理无关类型之间的变换;它会暴发一个新的值,这多少个值会有与原有参数(expression)有完全相同的比特位。

咋样是无关类型?我从不弄了解,没有找到好的文档来表明类型之间到底都有些什么关联(除了类的延续以外)。后半句倒是看出了reinterpret_cast的字面意思:重新解释(类型的比特位)。咱们实在可以随心所欲将一个类型值的比特位交给另一个序列作为它的值吗?其实不然。

IBM的C++指南里倒是明确告知了大家reinterpret_cast可以,或者说应该在什么样地点用来更换运算符:

  • 从指针类型到一个足足大的整数类型
  • 从整数类型或者枚举类型到指针类型
  • 从一个针对性函数的指针到另一个见仁见智品种的针对函数的指针
  • 从一个针对性对象的指针到另一个两样类其余指向对象的指针
  • 从一个针对性类函数成员的指针到另一个针对不同门类的函数成员的指针
  • 从一个指向类数据成员的指针到另一个针对不同连串的数目成员的指针

不过我在Xcode中测试了一晃,事实上reinterpret_cast的选取并不囿于在上方所说的几项的,任何类型的指针之间都得以相互转换,都不会获取编译错误。上述列出的几项,可能
是Linux下reinterpret_cast使用的限定,也说不定是IBM推荐大家利用reinterpret_cast的方式。

于是总结来说:reinterpret_cast用在任意指针(或引用)类型之间的变换;以及指针与充足大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。

(所谓“丰盛大的平头类型”,取决于操作系统的参数,假倘使32位的操作系统,就需要整型(int)以上的;倘使是64位的操作系统,则最少需要长整型(long)。具体尺寸可以透过sizeof运算符来查看)。

reinterpret_cast有何意义

从下边对reinterpret_cast介绍,可以感到出reinterpret_cast是个很强大的运算符,因为它能够漠视种族隔离,随便搞。但就像生物的规则,不适合自然规律的人身自由杂交只会取得无法长时间生存的物种。随目的在于不同序列之间利用reinterpret_cast,也会导致程序的损坏和不可以运用。

比如下边的代码

typedef int (*FunctionPointer)(int); 
int value = 21; 
FunctionPointer funcP; 
funcP = reinterpret_cast<FunctionPointer> (&value); 
funcP(value); 

先用typedef定义一个针对函数的指针类型,所针对的函数接受一个int类型作为参数。然后我用reinterpret_cast将一个整型的地点转换成该函数类型并赋值给了相应的变量。最后,我还用该整型变量作为参数交给了指向函数的指针变量。

这么些过程编译器都成功地编译通过,不过假诺运行我们就会得到“EXC_BAD_ACCESS”的周转错误,因为我们通过funcP所指的地址找到的并不是函数入口。

测算,reinterpret_cast尽管看似强大,功效却没有那么广。IBM的C++指南、C++之父Bjarne
Stroustrup的FAQ网页
MSDN的Visual
C++
也都提议:错误的利用reinterpret_cast很容易导致程序的不安全,唯有将转移后的类型值转换回到其原始类型,这样才是科学利用reinterpret_cast方式。

如此这般说起来,reinterpret_cast转换成另外序列的目的只是暂时地隐藏自己的什么(做个卧底?),要真想利用相当值,仍旧需要让其暴露本来面目才行。这究竟它在C++中有其何等存在的市值啊?

MSDN的Visual C++ Developer
Center

给出了它的应用价值:用来帮忙哈希函数。下面是MSNDN上的例证:

// expre_reinterpret_cast_Operator.cpp
// compile with: /EHsc
#include <iostream>
// Returns a hash code based on an address
unsigned short Hash( void *p ) {
    unsigned int val = reinterpret_cast<unsigned int>( p );
    return ( unsigned short )( val ^ (val >> 16));
}

using namespace std;
int main() {
    int a[20];
    for ( int i = 0; i < 20; i++ )
        cout << Hash( a + i ) << endl;
}

//如果跟我一样是64位的系统,可能需要将unsigned int改成 unsigned long才能运行。

 

这段代码是如何呈现哈希的思想,暂时不做探索,但最少看Hash函数里面的操作,也能体味到,对整数的操作显著要比对地址操作更便宜。在聚集中存放整型数值,也要比存放地方更具有扩大性(当然如若存void
*扩张性也是同样很高的),唯一损失的或者就是存取的时候整型和地方的转移(那一点一滴可以忽略不计)。

 

转自:

http://www.cnblogs.com/ider/archive/2011/07/30/cpp\_cast\_operator\_part3.html

相关文章