很多人对C++中的几个类型转换操作符是有些陌生的,并且代码中类型转换也从来都是用C风格的强制类型转换。而且会有些人认为使用这些操作符麻烦,不方便或者没必要。下面是对网上一些资料的总结,主要分析一下两种方式的用法和各自优点。
C风格的类型转换
显示强制类型转换:用法为 type (expression)或(type)expression
经强制类型转换运算符运算后,返回一个具有type类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变。如:
  1.   int nVar=0xab65;
  2.   char cChar=char (nVar);
上述强制类型转换的结果是将整型值0xab65的高端两个字节删掉,将低端两个字节的内容作为char型数值赋值给变量cChar,而经过类型转换后nVar的值并未改变。
隐式强制类型转换:
  隐式类型转换发生在赋值表达式和有返回值的函数调用表达式中。在赋值表达式中,如果赋值符左右两侧的操作数类型不同,则将赋值符右边操作数强制转换为赋值符左侧的类型数值后,赋值给赋值符左侧的变量。在函数调用时,如果return后面表达式的类型与函数返回值类型不同,则在返回值时将return后面表达式的数值强制转换为函数返回值类型后,再将值返回。

 
C++新增的类型转换操作符
static_cast: 用法为 static_cast < type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
  1. 用于类层次结构中基类和子类之间指针或引用的转换。

    • 进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
    • 进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
  2. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  3. 把空指针转换成目标类型的空指针。
  4. 把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

主要特性如下:
  • static_cast 在编译时使用类型信息执行转换,在转换执行必要的检测(诸如指针越界计算, 类型检查),其操作数相对是安全的。reinterpret_cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换, 如:
  1. int n=9;
  2. double d=static_cast < double > (n);

上面的例子中, 我们将一个变量从 int 转换到 double。 这些类型的二进制表达式是不同的。 要将整数 9 转换到 双精度整数 9,static_cast 需要正确地为双精度整数 d 补足比特位。其结果为 9.0。而reinterpret_cast 不会有这样的操作。
  • 在一类东西都可以转, 但是不是一类的就不能转。即, 语义上说不通的, 两个完全不同的数据类型 static_cast 是拒绝工作的。比如你想把一个指针转成浮点数。

 
dynamic_cast: 用法为 dynamic_cast < type-id > ( expression )
该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
主要特性如下:
  • dynamic_cast用于一颗类继承树上转换时,将利用 RTTI 在运行时检查。一般用于下行转换,即将基类指针转换为派生类指针。比如,
  1. class A {};
  2. class B : public A {};
  3. A* a=new B();

这时, 可以用 dynamic_cast 做 类型转换, 把 a 转成 B*。和 static_cast 不同, dynamic_cast 会检查一下 a 到底是不是指向一个B,如果转不了, 将返回一个 NULL。
所以,这种情况下dynamic_cast比static_cast更严格更安全,但执行效率上比static_cast要差。
注意:这里要求派生类要有虚拟函数,否则编译不能够通过。而static_cast则无此要求。

 
  reinterpret_cast 用法为 reinterpret_cast < type-id > (expression)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
如:它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。该运算符的用法比较多。

主要特性如下:
  • reinterpret_cast 比 static_cast 更接近 C 的强制转换。它可以实现看起来没关系的两种类型的转换,当然它比 static_cast 危险。

 
const_cast 用法为 const_cast < type-id >  (expression)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外,type_id和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

注意:某些情况下const_cast是比reinterpret_cast更加危险的操作,它的使用一定要慎重。

 
通过以上两种方式的用途的分析会发现:C风格的强制类型转换可以完成C++中四个操作符的所有功能,那么这些操作符就显得很麻烦,很没必要。
但实际上,正是因为C风格的强制类型转换太过粗暴,可以完成几乎所有类型转换的操作,这会使得编译器很难捕捉误用。如:代码中误写的极危险的或者不同于开发者本意的 类型转换操作都能直接编译通过,这会非常影响代码安全性。
同时,C风格类型转换在程序中很难被发现,编辑器里不能方便的查找到类型转换。而因为类型转换操作存在很大的安全隐患,这会造成代码开发维护上极大不便。

 
总之,C++类型转换操作符的处理方式,能让程序员更清晰的表达他们的真实意图,也使编译器能捕捉到更多的错误,避免类型转换中的误操作。如:
www.378114.com
www.wabaoer.com
www.lrznet.com
www.37fa.cn
www.ymsb.net
www.haoym.net
www.foodseo.cn
www.equban.com
www.qqphp.cn
wanwu.foodseo.cn
www.di114.cn
jingyou.di114.cn
 
  1. int a = 7;
  2. double* p1 = (double*) &a; // ok(但指向的并非 double 类型的对象)
  3. double* p2 = static_cast<double *>(&a); // 错误
  4. double* p2 = reinterpret_cast<double *>(&a); // ok:我真的想这么干
  5. const int c = 7;
  6. int* q1 = &c; // 错误
  7. int* q2 = (int*)&c; // ok(但 *q2=2; 仍然是不合法的代码,而且有可能失败)
  8. int* q3 = static_cast<int *>(&c); // 错误:static_cast 不能去除 const 属性
  9. int* q4 = const_cast<int *>(&c); // 我的确想这么干
总的来说,应该尽量避免使用类型转换,实际工程代码中经常会用到的也就是类层次结构中基类和子类之间的转换,所以static_cast和dynamic_cast比较常用。最后,尽管类型转换操作符的方式没有非常明显的优势,还是建议在C++工程中,应该尽量避免C风格的类型强转。使用类型转换操作符的方式进行类型转换,是一种好的良好编码的习惯,他们会使你受益。

转载于:https://blog.51cto.com/lrznet/585284

C++风格的类型转换操作符与C风格的强制类型转换相关推荐

  1. C++ 类型转换 :C语言的类型转换、C++的四种强制类型转换、explicit

    文章目录 C语言中的类型转换 隐式类型转换 显式类型转换 C++ 强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast explici ...

  2. linux 强制类型转换,C++ 新标准下的强制类型转换详解

    使用标准C++的类型转换符:static_cast.dynamic_cast.reinterpret_cast和const_cast. static_cast 用法:static_cast (expr ...

  3. java object强制类型转换_scala object 转Class Scala强制类型转换

    asInstanceOf[T] 将对象类型强制转换为T类型. 还是由于泛型存在类型擦除的原因,1.asInstanceOf[String]在运行时会抛出ClassCastException异常,而Li ...

  4. C++ 四种类型转换操作符

    在c++中进行类型转换只需要在变量前加上变量类型,并且转换是双向的. 例如: int i = 0: double d = 1.9:int i1 = (int) d: double d1 = (doub ...

  5. 谁说 C++ 的强制类型转换很难懂?

    作者 | 樱雨楼 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 在上篇与中篇中,我们讨论了隐式类型转换及其与函数重载之间的相关话题.本篇将要讨论的即为类型转换的另一大分支--强制类型转 ...

  6. C++ 四种强制类型转换

    C++ 类型转换(C风格的强制转换): 在C++基本的数据类型中,可以分为四类:整型,浮点型,字符型,布尔型.其中数值型包括 整型与浮点型:字符型即为char. (1)将浮点型数据赋值给整型变量时,舍 ...

  7. C++中的向上类型转换和向下类型转换+四种强制类型转换

    转自博客:http://blog.csdn.net/wangweitingaabbcc/article/details/7720979# 在c++的世界中有这样两个概念,向上类型转换,向下类型转换,分 ...

  8. C/C++ 之 C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

    文章转载自:https://www.cnblogs.com/chenyangchun/p/6795923.html .在了解这块时,发现了这篇文档,感觉写的很不错! c强制转换与c++强制转换 c 语 ...

  9. char强制类型转换为int_为强制类型转换正名

    为强制类型转换正名​www.yexiaochen.com 引子 强制类型转换是JavaScript开发人员最头疼的问题之一, 它常被诟病为语言设计上的一个缺陷, 太危险, 应该束之高阁. 作为开发人员 ...

最新文章

  1. mysql 列累加计算
  2. oracle中值集限定词为灰色,《Oracle从入门到精通》读书笔记第四章 SQL语言基础之一...
  3. 中国甲真菌病药物行业市场供需与战略研究报告
  4. 中国接种环行业市场供需与战略研究报告
  5. docker使用国内仓库
  6. kotlin中的异常处理_Kotlin异常处理
  7. 深入理解Angular2变化监测和ngZone
  8. FT5X06 如何应用在10寸电容屏
  9. ICMP(网际控制报文协议)
  10. FPGA STA(静态时序分析)
  11. abaqus如何并行计算_Abaqus软件与并行计算的硬件配置
  12. 根据开始日期,结束日期,计算出日历上有几周的方法
  13. 开机预读快还是不预读快_启用预读为网页浏览提速
  14. 大童保险发生工商变更:安信信托彻底退出,德弘资本晋升为大股东
  15. poj 2044 weather forcast
  16. 报错Cannot mix different versions of joi schemas解决方法
  17. 四点之间最短路(spfa+优先队列+枚举优化)UESTC1955喜马拉雅山上的猴子
  18. 感谢十二年的陪伴——分享回归,不忘初心(Eastmount博客总结及未来规划)
  19. java minma_Java Core.minMaxLoc方法代码示例
  20. Android StatusBar 黑底白字

热门文章

  1. 计算机网络课程改革,《计算机网络技术》课程改革
  2. 杭电oj 2099 java实现
  3. 【淘客基地各项目拉新活动海报已开启】公告
  4. 小程序多图上传至阿里云云服务器
  5. 单阶段目标检测算法之YOLOv1详解
  6. 图片去水印工具下载-图片去水印无痕软件免费
  7. CSS—新增标签标签
  8. ANSI/ESD S541-2019 用于保护静电放电敏感物品 - 包装材料,中文,英文发布
  9. 人人网2015研发笔试卷C
  10. 电脑桌面云便签软件怎么设置禁止移动窗体固定便签显示位置?