有时我们希望显式地将对象强制类型转换成另外一种类型。例如,如果想在下面的代码中执行浮点数除法:

  int i, j;

  double slope = i / j;

  就要使用某种方法将i和/或j显式地转换成double,这种方法称作强制类型转换。

命名的强制类型转换

  一个命名的强制类型转换具有如下形式:

  cast_name<type>(expression);

  其中,type是转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值,cast-name是static_cast, dynamic_cast, const_cast和reinterpret_cast中的一种。dynamic_cast支持运行时类型识别。cast-name指定了执行的是哪种转换。

static_cast

  任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_const。

  例如,通过将一个运算对象强制转换成double类型就能使表达式执行浮点数除法:

  double slope = static_cast<double>(j) / i;

  当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。此时,强制类型转换告诉程序的读者和编译器:我们知道并且不在乎潜在的精度损失。一般来说,如果编译器发现一个的算术类型试图赋值给较小的类型,就会给出警告信息;但是当我们执行了显式的类型转换后,警告信息就会被关闭了。

  static_cast对于编译器无法自动执行的类型转换也非常有用。例如,我们可以使用static_cast找回存在于void*指针中的值:

  void *p = &d;  //正确:任何非常量对象的地址都能存入void*

  //正确:将void*转换回初始的指针类型

  double *dp = static_cast<double*>(p);

当我们把指针存放在void*中,并且使用static_cast将其强制转换回原来的类型时,应该确保指针的值保持不变。也就是说,强制转换的结果将与原始的地址值相等,因此我们必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义的后果。

const_cast

  const_cast只能改变运算对象的底层const

  const char *pc;

  char *p = const_cast<char*> (pc);  //正确:但是通过p写值是未定义的行为

对于将常量对象转化为非常量对象的行为,我们一般称之为”去掉const性质(cast away the const)“。一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为。然而如果对象是一个常量,再使用const_cast执行写操作就会产生未定义的后果。

  只有 const_cast能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量属性都将引发编译器错误。同样地,也不能用const_cast改变表达式的类型:

const char *cp;
//错误:static_cast不能转换掉const性质
char* q = static_cast<char*> (cp);
static_cast<string> (cp); //正确,字符串字面值转换成string类型
const_cast<string>(cp); //错误,const_cast只改变常量属性

  总结来说:const_cast只能改变底层const,即它只能改变对象或引用的const属性,不能改变对象的const属性。const_cast即可以添加const性质,也可以删除const性质。

reinterpret_cast

  reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。举个例子,假设有如下的转换:

  int *ip;

  char *pc = reinterpret_cast<char*>(ip);

我们必须牢记pc所指的真实对象是int而非字符,如果把pc当成一个普通的字符指针使用就可能在运行时发生错误。例如:

  string str(po);

可能导致异常的运行时行为。

  使用reinterpret_cast是非常危险的,用pc初始化的例子很好地证明了这一点。其中的关键问题是类型改变了,但编译器没有给出任何警告或者错误的提示信息。当我们用一个int的地址初始化pc时,由于显式地声称这种转换合法,所以编译器不会发出任何警告或错误信息。接下来再使用pc时就会认定它的值是char*类型,编译器没法知道它实际存放的是指向int的指针。

dynamic_cast

  只用于对象的指针和引用. 当用于多态类型时,它允许任意的隐式类型转换以及相 反过程. 不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast 会检查操作是否有效. 也就是说, 它会检查转换是否会返回一个被请求的有效的完整对象。检测在运行时进行. 如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL. 对于引用 类型,会抛出bad_cast异常 .

C++的几种强制类型转换的更多相关文章

  1. C#中,三种强制类型转换的对比

    在C#中,我们可以看到三种强制类型转换,比如强制转换成有符号32位整型,可以找到下面三种方式: ① (int)()                ②Convert.ToInt32()          ...

  2. 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...

  3. C++中的关键字用法--- 四种强制类型转换的总结

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast 1. C风格的强制类型转换(Type Cast)很简单,不管什么类 ...

  4. C++ 4种强制类型转换

    C++的四种强制类型转换为:static_cast.const_cast.reinterpret_cast和dynamic_cast 类型转换的一般形式:cast-name(expression); ...

  5. [转载]C++中四种强制类型转换方式

    C++中四种强制类型转换方式 原文地址:http://www.cnblogs.com/home123/p/6763967.html 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单( ...

  6. 【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

    强制类型转换 1. static_cast 2. dynamic_cast 3. const_cast 4. reinterpret_cast 5. 为什么要需要四种类型转换? 1. static_c ...

  7. C++开发必看 四种强制类型转换的总结 [转]

    一.C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:     TYPE b = (TYPE)a 二.C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. co ...

  8. C++四种强制类型转换关键字

    C语言使用强制类型转换(Type Cast)很简单,不管什么类型的转换,形式都如下: TYPE b = (TYPE)a; c++提供了4种类型转换操作符来应对不同场合的应用. const_cast   ...

  9. C++开发必看 四种强制类型转换的总结

    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. const_cast ...

随机推荐

  1. PostgreSQL Replication之第十二章 与Postgres-XC一起工作(4)

    12.4 性能优化 Postgres-XC不是一个奇特的PostgreSQL版本,而是一个真正的分布式系统.这意味这,您不能只存储数据,希望事情超出服务器之外的快速,高效.如果您想优化速度,思考数据是 ...

  2. CSS自定义弹出框

    <script type="text/javascript" language="javascript"> function sAlert(str) ...

  3. android与后台请求的例子

    public static ClientResponse SendClientRequest(List<BasicNameValuePair> params){ ClientRespons ...

  4. 封装upload文件上传类

    <?php //封装php中的单文件(图片)上传类 /*  //参数1:$file 文件数组  5个属性值 name,type,size,tmp,error   //参数2:文件保存的路径$pa ...

  5. 夺命雷公狗---Thinkphp----1之目录介绍

    ThinkPHP框架 特点: 免费开源 敏捷开发(快速开发) 面向对象 MVC思想 yii,ci之类的框架都有这些特点.是06年到现在的一个老牌框架,现在还是个很不错的框架 可以在thinkphp的官 ...

  6. PTPX Power Analysis Flow

    PrimeTime PX工具是PrimeTime工具内的一个feature. PTPX的功耗分析,可以报告出chip,block,cell的各个level的功耗. 使用PTPX可以分析的功耗的方式: ...

  7. HTML5的自定义属性data-* 的用法解析

    人们总喜欢往HTML标签上添加自定义属性来存储和操作数据.但这样做的问题是,你不知道将来会不会有其它脚本把你的自定义属性给重置掉,此外,你这样做也会导致html语法上不符合Html规范,以及一些其它副 ...

  8. mysql单表查询&&多表查询(职员表14+9)

    dept(deptno,dname,loc) emp(empno,ename,job,mgr,hiredate,sal,COMM,deptno) salgrade(grade,losal,hisal) ...

  9. 阿里BCG重磅报告《人工智能,未来致胜之道》

    阿里BCG重磅报告<人工智能,未来致胜之道> 阿里云研究中心.波士顿咨询公司以及Alibaba Innovation Ventures合作共同推出的<人工智能:未来制胜之道>这 ...

  10. tomcat启动startup.bat一闪而过 转

    遇到很多次运行startup.bat后,一个窗口一闪而过的问题,但是从来没去纠正怎样修改配置才是正确的,现在从网上查阅的资料整理如下:tomcat在启动时,会读取环境变量的信息,需要一个CATALIN ...