博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++中强制类型转换
阅读量:6248 次
发布时间:2019-06-22

本文共 2721 字,大约阅读时间需要 9 分钟。

C++强制类型转换

C++中的强制类型转换虽然兼容C语言中的强制类型转换。但是并不建议在C++中使用C语言风格的强制类型转换。C++中的强制类型转换共有4个关键字分别是:static_cast,const_cast,reinterpret_cast,dynamic_cast.

static_cast

用于将一种数据类型转换成另一种数据类型,使用格式如下:

变量1 = static_cast(另外一种数据类型变量或表达式);
例如:

int a = 1;float b;b = static_cast
(a); //类似于C语言中的b = (float)a;

const_cast

用于去除指针和引用的常量性,不能去除变量的常量性。使用格式如下:

指针或引用1 = const_cast(带常量性的指针或引用2);
例如:

#include 
using namespace std;int main(){ int a = 10; const int *p = &a; // 被const修饰,不能使用该指针修改其指向内容的值 int *q; q = const_cast
(p); // 去除p的常量性给q,如果不去除直接赋值会报错 *q = 20; cout<<"a的地址为:"<<&a<<" a的值为:"<
<

执行结果如下:

a的地址为:0x61ff14a a的值为:20  *q指向的地址为:0x61ff14a *q的值为:20

为了加深理解,我们再看如下一段代码:

#include 
using namespace std;const int & Add5(int &a);int main(){ const int a = 10; //a的值不允许修改 int b = 20; const int *p = &a; //被const修饰,不能使用该指针修改其指向内容的值 int *q; q = const_cast
(p); //去除p的常量性给q,如果不去除直接赋值会报错 *q = 20; cout<<"a的地址为:"<<&a<<" a的值为:"<
<
(Add5(b)); //去掉函数的const属性,不去掉就赋值给不带const的引用会报错 cout<<"调用加5函数之后"<

执行结果如下:

a的地址为0x61ff10 a的值为:10*q指向的地址为:0x61ff10 *q的值为:20b的地址为:0x61ff0c b的值为:20调用加5函数之后引用m指向的地址为:0x61ff0c 引用m指向的值为:25

上面这段程序有两点说明:

  1. 对变量a加上了const属性,因此a的值是不会被程序所改变的。即使我们将指向a的指针的const属性去掉重新赋值,也不会改变。但是会出现变量a和指针q指向地址相同,但值不同的现象。
  2. 对变量b的操作我们可以看出,const_cast不仅仅能去掉指针的const,也能去掉引用的const。不仅仅能去掉变量表达式的const也能去掉函数的const。
    最后,在强调一遍。const_cast不能去掉变量的const.这是编程安全的基础。像下面这种操作是错误的。除了const之外,const_cast也能去掉volatile属性,和去掉const一样。
const int a = 10;int b = const_cast
(a); //变量的const属性去不掉,错误

reinterpret_cast

reinterpret_cast这种强制类型转换是一种非常强的强制类型转换,它可以将任意两个无关的指针或引用进行转换。上面的static_cast进行强制类型转换时,会进行编译时的类型安全检查,即你可以将int转成float,将子类引用(指针)转成父类引用(指针),子转父和父转子都可以,但父转子不安全。但是你不能使用static_cast将两个无关的东西进行转换,比如两个无关的类,因为编译器在编译的时候会检查这个转换是否可行,很明显不可行。

ClassB *p = &b;ClassA *q = static_cast
(p); //如果ClassA和ClassB有关系,编译能通过,否则不通过

但是如果使用的reinterpret_cast强制类型转换,就不会进行静态类型检查直接放行通过。当然如果这两个类如果没有关系,那么在运行的过程就会“跑偏出错”。为了防止在运行的过程中“跑偏”,我们除静态类型转换(static_cast)之外还需要一个动态的类型转换(dynamic_cast).

dynamic_cast

前面我们介绍过了static_cast,从名称上来看,两个一动(dynamic)一静(static)肯定有关系。我们知道static_cast会在编译的过程中进行安全性检查,而dynamic_cast会在运行的过程中进行安全性检查。这两个都带安全性检查可以防止错误的类型转换导致程序跑偏。

dynamic_cast既然是动态安全性检查,那么它肯定只能应用于指针或引用,不能用于内置的数据类型转换(内置的数据类型转换,在编译阶段由static_cast检查即可)。dynamic_cast不但检查两个指针是否属于同一个继承树(static_cast也检查这个),还会检测这种转换是否可行。如果可行就会返回一个新指针,并计算出为处理多继承的需要的必要的偏移量。如果不可行会返回NULL。因此即使我们使用reinterpret_cast强制类型转换骗过编译器编译成功,如果我们在使用前再使用dynamic_cast转换检测一下的话,还是能发现这个错误的转换的。

总结

  1. static_cast会进行静态的安全性检查,一般用于内置数据类型的转换和通常的类之间的转换。
  2. const_cast主要是用来去掉指针和引用的const和volatile类型。
  3. reinterpret_cast用于完全没有关系指针或引用之间的转换,比如字符指针转整形指针。
  4. dynamic_cast通常用于基类和派生类之间的相互转换。

转载于:https://www.cnblogs.com/yabin/p/6363531.html

你可能感兴趣的文章
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
计算机网络与Internet应用
查看>>
linux性能剖析工具
查看>>
计算机高手也不能编出俄罗斯方块——计算机达人成长之路(16)
查看>>
scikit-learn预处理实例之一:使用FunctionTransformer选择列
查看>>
Mars说光场(3)— 光场采集
查看>>
UE 正则表达式匹配某一标签内容
查看>>
Django 文件下载功能
查看>>
SystemCenter2012SP1实践(4)安装SCVMM
查看>>
JDBC使用TNS连接多节点Oracle
查看>>
iPhone和iPad开发图标基本知识
查看>>
2012年中国系统架构师大会 即将开幕
查看>>
区块链游戏导航,一个不错的生意!
查看>>
【iOS-cocos2d-X 游戏开发之十三】cocos2dx通过Jni调用Android的Java层代码(上)
查看>>
安装BOSH -在vSphere上通过BOSH工具大规模部署Cloud Foundry
查看>>
采用python的pyquery引擎做网页爬虫,进行数据分析
查看>>
阿里上市,他们如是说
查看>>
HTML将不再有版本号
查看>>
Eclipse代码中中文字显示很小的解决办法
查看>>
ArchLinux and LXDE and LXDM
查看>>