设为首页 加入收藏

TOP

4.11.3 显式转换(1)
2013-10-07 16:28:51 来源: 作者: 【 】 浏览:103
Tags:4.11.3 转换

4.11.3  显式转换(1)

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

  1. int i, j;  
  2. double slope = i/j;  

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

虽然有时不得不使用强制类型转换,但这种方法本质上是非常危险的。

命名的强制类型转换

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

  1. cast-name<type>(expression); 

其中,type是转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值。cast-name是static_cast、dynamic_cast、const_cast和reinterpret_cast中的一种。dynamic_cast支持运行时类型识别,我们将在19.2节(第825页)对其做更详细的介绍。cast-name指定了执行的是哪种转换。

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。例如,通过将一个运算对象强制转换成double类型就能使表达式执行浮点数除法:

  1. // 进行强制类型转换以便执行浮点数除法  
  2. double slope = static_cast<double>(j) / i; 

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

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

  1. void* p = &d;   // 正确:任何非常量对象的地址都能存入void*  
  2. //正确:将void*转换回初始的指针类型  
  3. double *dp = static_cast<double*>(p);  

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

const_cast

const_cast只能改变运算对象的底层const(参见2.4.3节,第63页):

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

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

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

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

const_cast常常用于有函数重载的上下文中,关于函数重载将在6.4节(第232页)进行详细介绍。

reinterpret_cast

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

  1. int *ip;  
  2. char *pc = reinterpret_cast<char*>(ip); 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇4.11.2 其他隐式类型转换 下一篇优化C++代码(4):消除冗余代码

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: