Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意?
  A:转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:
代码:
  int i;
  double d;
  i = (int) d;或者:i = int (d);

  对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast', 'static_cast', 'dynamic_cast' 和 'const_cast',目的在于控制类(class)之间的类型转换。
代码:
  • reinterpret_cast<new_type>(expression)
  • dynamic_cast<new_type>(expression)
  • static_cast<new_type>(expression)
  • const_cast<new_type>(expression)
  1. static_cast:静态类型转换
  2. const_cast:常量类型转换
  3. dynamic_cast:动态类型转换
  4. reinterpret_cast:重新解释类型转换
1、dynamic_cast运算符
  该转换符用于将一个指向派生类的基类指针或引用转换为派生类的指针或引用
  注意:dynamic_cast转换符只能用于含有虚函数的类,其表达式为 dynamic_cast<类型>(表达式)
  其中的类型是指把表达式要转换成的目标类型,比如含有虚函数的基类B和从基类B派生出的派生类D,则:
  B *pb; 
  D *pd, md;  
  pb = &md; 
  pd = dynamic_cast<D *>(pb); 
  最后一条语句表示把指向派生类D的基类指针pb转换为派生类D的指针,然后将这个指针赋给派生类D的指针pd,有人可能会觉得这样做没有意义,既然指针pd要指向派生类为什么不pd = &md;这样做更直接呢?有些时候我们需要强制转换,比如如果指向派生类的基类指针B想访问派生类D中的除虚函数之外的成员时就需要把该指针转换为指向派生类D的指针,以达到访问派生类D中特有的成员的目的,比如派生类D中含有特有的成员函数g(),这时可以这样来访问该成员dynamic_cast<D *>(pb)->g();因为dynamic_cast转换后的结果是一个指向派生类的指针,所以可以这样访问派生类中特有的成员。但是该语句不影响原来的指针的类型,即基类指针pb仍然是指向基类B的。如果单独使用该指针仍然不能访问派生类中特有的成员。一般情况下不推见这样使用dynamic_cast转换符,因为dynamic_cast的转换并不会总是成功的,具体情况在后面介绍。
 
dynamic_cast的注意事项
  dynamic_cast转换符只能用于指针或者引用。dynamic_cast转换符只能用于含有虚函数的类。dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果能成功转换则转换之,如果转换失败,如果是指针则反回一个0值,如果是转换的是引用,则抛出一个bad_cast异常,所以在使用dynamic_cast转换之间应使用if语句对其转换成功与否进行测试,比如pd = dynamic_cast(pb); if(pd){…}else{…},或者这样测试if(dynamic_cast(pb)){…}else{…}。
 
  因此,dynamic_cast操作符一次执行两个操作。首先验证被请求的转换是否有效,只有转换有效,操作符才实际进行转换。基类的指针可以赋值为指向派生类的对象,同样,基类的引用也可以用派生类对象初始化,因此,dynamic_cast操作符执行的验证必须在运行时进行。
 
2、const_cast操作符
  其表达式为 const_cast<类型>(表达式)
  其中类型指要把表达式转换为的目标类型。该操作符用于改变const和volatile,const_cast最常用的用途就是删除const属性,如果某个变量在大多数时候是常量,而在某个时候又是需要修改的,这时就可以使用const_cast操作符了。
const_cast操作符不能改变类型的其他方面,他只能改变const或volatile,即const_cast不能把int改变为double,但可以把const int改变为int。const_cast只能用于指针或引用。
const_cast的用法举例
比如:int a=3; const int *b=&a; int* c=const_cast(b); *c=4; cout<<a<<*c;这时输出两个4,如果不使用const_cast转换符则常量指针*c的值是不能改变的,在这里使用const_cast操作符,通过指针b就能改变常量指针和变量a的值。
 
3、static_cast操作符
  该操作符用于非多态类型的转换,任何标准转换都可以使用他,即static_cast可以把int转换为double,但不能把两个不相关的类对象进行转换,比如类A不能转换为一个不相关的类B类型。static_cast本质上是传统c语言强制转换的替代品。
 
  static_cast(静态转换)执行非多态的转换,用于代替C中通常的转换操作。因此,被做为隐式类型转换使用。显式告诉编译器,不关心转换后精度损失。比如:
int i;
float f = 166.7f;
i = static_cast<int>(f);
此时结果,i的值为166。

4.reinterpret_cast

interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。如:int i; char *ptr="hello freind!"; i=reinterpret_cast<int>(ptr);这个转换方式很少使用。

  reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。

  • 从指针类型到一个足够大的整数类型
  • 从整数类型或者枚举类型到指针类型
  • 从一个指向函数的指针到另一个不同类型的指向函数的指针
  • 从一个指向对象的指针到另一个不同类型的指向对象的指针
  • 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
  • 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
  • //基本类型指针的类型转换

    double d=9.2;

    double* pd = &d;

    int *pi = reinterpret_cast<int*>(pd);  //相当于int *pi = (int*)pd;

    //不相关的类的指针的类型转换

    class A{};

    class B{};

    A* pa = new A;

    B* pb = reinterpret_cast<B*>(pa);   //相当于B* pb = (B*)pa;

C++中四种类型转换方式(ynamic_cast,const_cast,static_cast,reinterpret_cast)的更多相关文章

  1. c++ --> c++中四种类型转换方式

    c++中四种类型转换方式   c风格转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少缺点, 1)它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向 ...

  2. C++中四种类型转换方式

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  3. C++中四种类型转换以及const_cast是否能改变常量的问题

    we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...

  4. 【转】C++四种类型转换方式

    C++四种类型转换方式 https://blog.csdn.net/lv_amelia/article/details/79483579 C风格的强制类型转换(Type Case)很简单,不管什么类型 ...

  5. 【C++】类型转换简述:四种类型转换方式的说明及应用

    本文主要简述在C++中四种类型转换的方式:static_cast.reniterpret_cast.const_cast和dynamic_cast. 在介绍C++类型转换方式之前,我们先来看看C语言的 ...

  6. [转]C++中四种类型转换符的总结

    C++中四种类型转换符的总结 一.reinterpret_cast用法:reinpreter_cast<type-id> (expression)    reinterpret_cast操 ...

  7. Web.xml中四种验证方式

    源地址:https://blog.csdn.net/imimi_/article/details/78805642 <security-constraint> 的子元素 <http- ...

  8. C++四种类型转换方式。

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  9. OC中四种遍历方式

    标准的C语言for循环.Objective-C 1.0出现的NSEnumerator.Objective-C 1.0出现的for in快速遍历.块遍历. 遍历的话,一般是NSArray.NSDicti ...

随机推荐

  1. wifidog接口文档(转)

    目录(?)[-] 网关心跳协议 请求信息 回复格式 例子 用户状态心跳协议 请求格式 注意 回复格式 状态码 例子 跳转协议 请求格式 例子 注册协议 请求格式 例子 wifidog是搭建无线热点认证 ...

  2. Ext JS isField为空或不是对象问题的解决

    在做Ext Js的DataGrid的时候经常会遇到这种问题,火狐谷歌没有问题,IE8及以下版本就无法通过,经调试会提示: “isField为空或不是对象问题的解决” 这通常是我们在js代码中多加了一个 ...

  3. ASP入门(十)-Session对象

    在ASP中,有两个内部对象可以进行一些信息存储,它们是 Application 对象和 Session 对象,其中 Application 对象是对于整个应用程序期间而言的,它对于所有访问网站的用户来 ...

  4. python 几种常用测试框架

    测试的常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过se ...

  5. [信息检索] 第一讲 布尔检索Boolean Retrieval

    第一讲 布尔检索Boolean Retrieval 主要内容: 信息检索概述 倒排记录表 布尔查询处理 一.信息检索概述 什么是信息检索? Information Retrieval (IR) is ...

  6. Android studio 自己定义打包APK名称

    Android Studio打包应用默认生成的apk名称是:app-release.apk .假设我们要让生成的apk名跟我们版本号包名有联系的话.那我们就要自己定义生成的apk名了,要怎么做呢. 我 ...

  7. 【高德地图Android SDK】视频教学

    前两天参加了高德在北航举办的公开课,感觉非常不错.完成老师布置的作业之后,还顺利地拿到了高德开发者认证证书!! 现在来跟大家分享一下,如何快速学习[高德地图Android SDK]的开发.一天包会!连 ...

  8. IE6.0 PNG背景透明图片插件

    <!--[if lte IE 6]><script src="http://xian.qq.com/js/2013js/2013index/DD_belatedPNG_0. ...

  9. LintCode: Number of Islands

    分析:经典连通分量问题 图: 节点:所有1的位置 边:两个相邻的1的位置有一条边 BFS/DFS (DFS使用递归,代码较短) 选一个没标记的点,然后搜索,扩展4个邻居(如果有),直到不能扩展 每一次 ...

  10. [工具IDE]工具与书籍

    看到几个还不错的资源,记录于下: 一.使用 JavaScript 写的操作系统: http://www.admin10000.com/document/3811.html 演示地址参考:http:// ...