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 = ;
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 >> ));
} using namespace std;
int main() {
int a[];
for ( int i = ; i < ; 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

【转】C++标准转换运算符reinterpret_cast的更多相关文章

  1. C++标准转换运算符reinterpret_cast

    C++标准转换运算符reinterpret_cast reinterpret_cast <new_type> (expression) reinterpret_cast运算符是用来处理无关 ...

  2. C++标准转换运算符

    C++类型转换在实际编程中会经常使用,其实,本质上对象的类型用来解释(interpret)对象.因为,每个对象都占据一块内存空间,这块内存空间存放了一段二进制数据.通过标记该对象的类型,告诉如何看待这 ...

  3. C++标准转换运算符const_cast

    前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor ...

  4. C++标准转换运算符 --四种

    具体归纳如下: reinterpret_cast 函数将一个类型的指针转换为另一个类型的指针. 这种转换不用修改指针变量值存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可做到.rein ...

  5. C++标准转换运算符dynamic_cast

    dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为它涉及到编译器的属性设置,而且牵扯到的面向对象的 ...

  6. C++标准转换运算符static_cast

    该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性.   中文名 暂无 外文名 static_cast 分    类 强制类型转换 类    型 C++ s ...

  7. 【转】C++标准转换运算符static_cast

    static_cast<new_type> (expression) 虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用 ...

  8. 【转】C++标准转换运算符const_cast

    const_cast转换符是用来移除变量的const或volatile限定符. 对于const变量,我们不能修改它的值,这是这个限定符最直接的表现.但是我们就是想违背它的限定希望修改其内容怎么办呢? ...

  9. const_cast标准转换运算符

    #include <iostream> using namespace std; class A { public: A() { a=; } public: int a; }; void ...

随机推荐

  1. lnk快捷方式变记事本打开还原,桌面图标变lnk还原方法

    今天天碰到一坑爹问题,打开一个.ini文件自动设置用记事本打开,所有快捷方式都变成记事本打开了,如下图,网上找了一些方法. windows中LNK文件打开方式恢复 相信有些用户曾试过错误地把LNK文件 ...

  2. centos6.8离线安装nginx

    rpm可从官网下载镜像解压获得,推荐从http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/下载 安装gcc rpm -ivh mpfr-2.4. ...

  3. API(Scanner、Random、ArrayList、String、Arrays、Math)

    Scanner import java.util.Scanner; /* public int nextInt(): to get a integer from keyboard public Str ...

  4. 解决浏览器跨域限制方案之JSONP

    一.什么是JSONP JSONP即:JSON with Padding,是一种解决因浏览器跨域限制不允许访问跨域资源的方法. JSONP是一个非官方的协议,它允许在服务器端返回javascript标签 ...

  5. vim学习之改头换面(基础配置)

    还记得在线有个维护博客园的学长说过,这网站的前端做的贼丑,今日一看果真如此.其实我想说毕竟干货多,没有那么多花花肠子.下面开始进入正题. 在入坑了sublime.vscode.atom.notepad ...

  6. Javaweb学习笔记——(二十二)——————文件上传、下载、Javamail

    文件上传概述      1.文件上传的作用          例如网络硬盘,就是用来上传下载文件的.          在网络浏览器中,时常需要上传照片 2.文件上传对页面的要求          上 ...

  7. 三十五、minishell(3)

    35.1 内容 在当前的 minishell 中,如果执行 date clear 命令等,minishell 会停止: 这是因为引入进程组的时候,mshell 放置在前台进程组,同时之后在子进程中又创 ...

  8. tensorflow---文字识别

    读取数据的三种方法: 1. feeding : providing data when running each step : classifier.eval(feed_dict={input:my_ ...

  9. Tensorflow Python 转 Java(一)

    一.背景描述 最近python的tensorflow想办法给弄到线上去.网络用的Tensorflow现成的包.写篇博客,记录下过成.数据用kaggle中的数据为例子. 数据地址: https://ww ...

  10. C语言编程程序的内存如何布局

    重点关注以下内容: C语言程序在内存中各个段的组成 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式 一:C语言程序的存储区域 由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过 ...