c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast

c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast

【版权声明】转载请注明出处 http://www.cnblogs.com/TenosDoIt/p/3175217.html

【目录】

引言

static_cast 定义

dynamic_cast 定义

举例:下行转换(把基类的指针或引用转换成子类表示)

举例:上行转换(把子类的指针或引用转换成基类表示)

举例: static_cast 用于基本类型之间、基本类型指针和空指针间的转换

reinterpret_cast 定义

举例:reinterpret_cast用法

const_cast 定义

举例:const_cast用法

总结


 

c语言中我们经常使用类似于 int a =(int)3.14等这种强制类型转换

标准c++的类型转换符:static_cast 、dynamic_cast、 reindivter_cast、 const_cast, 以下分别介绍他们的用法以及举例说明

以下代码编译运行环境:codeblock with gcc in win7(x64)

【1】static_cast 
用法:static_cast < type-id > ( exdivssion ) 

该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

①用于类层次结构中基类和子类之间指针或引用的转换。

  进行上行转换(把子类的指针或引用转换成基类表示)是安全的;

  进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。

注意:static_cast 不能转换掉exdivssion的const、volitale、或者__unaligned属性。

msdn官方解释:http://msdn.microsoft.com/en-us/library/c36yw7x9(v=vs.80).aspx

【2】dynamic_cast

用法:dynamic_cast < type-id > ( exdivssion )

该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;

如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast 的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast 更安全。

msdn官方解释:http://msdn.microsoft.com/en-us/library/cby9kycs(v=vs.80).aspx

 

举例:下行转换(把基类的指针或引用转换成子类表示)

需要注意的是如果基类中不含虚函数,dynamic_cast 下行转换编译会出错

复制代码
 1 #include<iostream>2 using namespace std;3 4 class father5 {6 public:7     void fun1()8     {9         cout<<"this is father fun1 call\n";
10     }
11     virtual void fun()
12     {
13         cout<<"this is father fun call\n";
14     }
15 };
16 
17 class son: public father
18 {
19 public:
20     void fun2()
21     {
22         cout<<"this is son fun2 call\n";
23     }
24     void fun()
25     {
26         cout<<"this is the son fun call\n";
27     }
28     int k;
29 };
30 
31 int main()
32 {
33     father *pf, f;
34     son *ps, s;
35 
36     pf = &f;// 基类的指针指向基类对象
37     ps = static_cast<son *>(pf);//这种转换是不安全的,行为是不确定的
38     if(ps != NULL)
39     {
40         ps->fun(); //在本文编译环境下,执行父类的fun
41         //本文编译环境下,一下语句可以执行
42         ps->fun2();
43         ps->k = 1;
44     }
45     ps = dynamic_cast<son *>(pf);//转换后ps = NULL
46     if(ps == NULL)
47         cout<<"dynamic_cast: ps = NULL\n";
48     cout<<"-----------------------------------------------------------------\n";
49     pf = &s; //基类指针开始指向子类对象
50     //此时,两种转换都是安全的
51     ps = static_cast<son *>(pf);
52     if(ps != NULL)
53     {
54         ps->fun();
55         ps->fun2();
56         ps->k = 1;
57     }
58     ps = dynamic_cast<son *>(pf);//转换后ps = NULL
59     if(ps != NULL)
60     {
61         ps->fun();
62         ps->fun2();
63         ps->k = 2;
64     }
65 }
复制代码

结果:

举例:上行转换(把子类的指针或引用转换成基类表示)

复制代码
 1 //类定义同上2 int main()3 {4     father *pf, f;5     son *ps, s;6 7     ps = &s;// 子类的指针指向子类对象8     //此时两种转换都是安全的9     pf = static_cast<father *>(ps);
10     if(pf != NULL)
11     {
12         pf->fun();
13     }
14     pf = dynamic_cast<father *>(ps);
15     if(pf != NULL)
16     {
17         pf->fun();
18     }
19 
20 }
复制代码

举例: static_cast 用于基本类型之间、基本类型指针和空指针间的转换(不能用于基本类型指针之间转换)。

注意:基本类型由于表示数值范围的不同,因此需要用户保证转换的安全。另外dynamic_cast不能用于此类转换

复制代码
 1 int main()2 {3     //基本类型间的转换,需要用户保证安全4     int a = 1000;5     char c = static_cast<char>(a);//不安全,1000超过了char的表示范围6     cout<<c<<endl;//输出空7     a = 49;8     c = static_cast<char>(a);//安全,输出字符‘1’9     cout<<c<<endl;
10     //c = dynamic_cast<char>(a); 错误
11     cout<<"-----------------------------------------------------------------\n";
12     //void *和基本类型指针的转换,需要用户保证转换安全
13     a = 49;
14     void *pv;
15     pv = &a;
16     int *pi = static_cast<int *>(pv);//void * 转换为int *
17     cout<<*pi<<endl; //输出49
18     //pi = dynamic_cast<int *>(pv); 错误
19     char *pc = static_cast<char *>(pv);//void *转char*
20     cout<<*pc<<endl;//输出字符‘1’
21     void *pv2 = static_cast<void *>(pc);// char * 转void *
22     cout<<*((char *)pv2)<<endl;输出字符‘1’
23 }
复制代码

 

【3】reinterpret_cast

用法:reinterpret_cast<type-id> (exdivssion)

reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。按照reinterpret的字面意思“重新解释”,即对数据的比特位重新解释。

IBM的C++指南 里明确告诉了我们reinterpret_cast可以,或者说应该在什么地方用来作为转换运算符:

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

总结来说:reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。

注意:static_cast 不能转换掉exdivssion的const、volitale、或者__unaligned属性。

msdn官方解释:http://msdn.microsoft.com/en-us/library/e0w9f63b(v=vs.80).aspx

举例:reinterpret_cast用法

复制代码
 1 int main()2 {3    int a = 49;4    int *pi = &a;5    char *pc = reinterpret_cast<char*>(pi);//int * 到char *,用户自己安全6    cout<<*pc<<endl; //输出字符"1"7    unsigned long b = reinterpret_cast<unsigned long>(pc);//char * 转 unsigned long8    cout<<b<<endl;//输出pc指向地址(即a的地址)对应的整数9    int *pi2 = reinterpret_cast<int *>(b);//unsigned long 转 int*
10    cout<<*pi2<<endl; //输出49
11 }
复制代码

【4】const_cast 

用法:const_cast<type-id> (exdivssion)

该运算符用来修改类型的const、volatile、__unaligned属性。除了const 、volatile、__unaligned修饰之外, type_id和exdivssion的类型是一样的。

常量指针被转化成非常量指针,并且仍然指向原来的对象;

常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

msdn官方解释:http://msdn.microsoft.com/en-us/library/bz6at95h(v=vs.80).aspx

举例:const_cast用法

复制代码
1 int main()
2 {
3    const int a = 100;
4    int *b = const_cast<int *>(&a);//const int * 转int *
5    cout<<*b<<endl; //输出100
6    cout<<&a<<" "<<b<<endl; //两者值相同,表明b指向a的地址,只是const属性变了
7 }
复制代码


总结:

类指针或引用的上行转换static_cast 和 dynamic_cast 都可以

类指针或引用的下行转换用dynamic_cast并且判断转换后是否为空

基本数据类型之间的转换用static_cast, 但是由于数值范围的不同,需要用户保证转换的安全性

不同类型之间的指针或引用的转换用reinterpret_cast,它的本质是对指向内存的比特位的重解释

消除数据的const、volatile、__unaligned属性,用const_cast

【版权声明】转载请注明出处 http://www.cnblogs.com/TenosDoIt/p/3175217.html

转载于:https://www.cnblogs.com/glllvwcc/p/5051393.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日用有余!国产中科方德桌面操作系统初体验

国产IT圈里最受关注的话题&#xff0c;除了芯片想必就是操作系统了。但真说起国产操作系统&#xff0c;大家是既熟悉又陌生&#xff0c;听说过的多而真正使用过的少。而伴随产业发展&#xff0c;市面上也涌现出众多国产操作软件&#xff0c;这些系统是否好用&#xff1f;能否满…

C# RichTextBox 做简单的HTML代码编辑器 ---------利用WinApi修正左侧显示行号 误差

说明&#xff1a;通过WinApi可以准确定准滚动位置。 //行号 生成显示 这里rtbLineNum用的 RichTextBox&#xff0c;也可以用其它private void ShowLineNum(){rtbLineNum.Text "";//计算行高&#xff0c;行数int linesLength 0;var pFirst tbEditor.GetPositionFr…

Angular - - angular.element

angular.element 将DOM元素或者HTML字符串一包装成一个jQuery元素。 格式&#xff1a;angular.element(element); element&#xff1a;包装成jquery对象的html字符串或者dom元素 jqLite提供的方法&#xff1a; addClass()after()append()attr()bind() – 不支持命名空间,选择器…

六、文章详情显示及点赞实现《iVX低代码/无代码个人博客制作》

注&#xff1a;iVX也有免费直播课《第八期直播课》 一、文章详情实现 上一节我们已经完成了首页的内容显示&#xff0c;那么此时我们完成点击后跳转到详情页内容。 那么此时由于我们需要跳转到详情页需要对应的数据ID&#xff0c;那么此时还需要给首页的文章数据对象数组一个…

System.CommandLine选项Option

前一篇简单看了一下CommandLine命令的使用&#xff0c;其实在一个命令行工具中&#xff0c;还有一个重要的点&#xff0c;那就是选项——Option&#xff0c;选项是为命提供参数&#xff0c;就好像C#中方法&#xff0c;Command就像方法&#xff0c;Option就像方法的参数&#xf…

【ArcGIS风暴】ArcGIS10.6栅格计算器(Raster Calculator)用法详解

扩展阅读: 【ArcGIS风暴】ArcGIS 10.2栅格计算器实用公式大全(经典珍藏版) 【ArcGIS风暴】栅格计算器(Raster Calculator)运算出现错误问题及解决方案汇总 文章目录 1. 栅格计算器简介2. 栅格计算器用法3. 简单算术运算4. 数学函数运算5. 空间分析函数运算1. 栅格计算器简…

三、登录页制作《iVX低代码/无代码个人博客制作》

注&#xff1a;iVX也有免费直播课《第八期直播课》 一、登录页实现 本节需要做的登录页如下&#xff1a; 该页面我们复习可以的值&#xff0c;首先设置整个页面页面的垂直和水平对其为居中&#xff0c;随后一个容器包裹对应的登录区域&#xff0c;此时我们创建一个页面命名为…

【C#控件详解】对话框类控件(打开文件,保存文件,选择字体和颜色)

在实际应用中,我们会用到各种各样的对话框,如打开文件,保存文件,选择字体和颜色等等。本文详细讲解C#中的颜色对话框、打开文件对话框、字体对话框、浏览文件夹对话框和保存文件对话框。 文章目录 1. ColorDialog对话框2. FolderBrowserDialog对话框3. FontDialog对话框4. …

动物界的再生一个故事

猪月薪5千&#xff0c;打算用20万建一个窝&#xff0c;老虎不允许&#xff0c;说私自建就是违章建筑&#xff0c;只允许向狼买。 狼是搞工程的&#xff0c;先用20万贿赂老虎取得开发权&#xff0c;再用50万元向老虎买这块地&#xff0c; 花10万元把猪圈盖好&#xff0c;向猪要价…

基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

【SPSS统计分析】SPSS19.0简体中文版安装教程(附SPSS19.0简体中文版下载)

spss19.0中文版是一款专业数据统计软件,受到各种社会学科的研究生、研究员的欢迎。软件能够对信息的采集、处理、分析进行全面评估和预测。spss19.0中文版新增加了广义线性混合模型、自动线性模型、一个统计网页入口portal和直复营销direct marketing功能等。另外,IBM 针对SP…

四、登录注册页功能实现《iVX低代码/无代码个人博客制作》

注&#xff1a;iVX也有免费直播课《第八期直播课》 首先打开在线编辑器进入我们的项目&#xff1a;https://editor.ivx.cn/ 一、登录页功能实现 上一节中已经完成了登录页的页面制作&#xff0c;那么这一节就开始对应的完成登录页的功能实现。 登录页的功能实现主要是对用户…

【ArcGIS风暴】中国756个气象台站分布Shapefile数据下载

在写论文时,通常要做研究区概况图,需要添加气象站点分布,或者在做气温或降水空间插值时,需要将气温和降水数据链接到气象台站上。气象数据通常可以到资源环境科学与数据中心去下载,为了使用的方便,本文分享中国区域756个气象台站shp格式矢量数据,如果你的研究区是西北五…

web上传大文件的配置

1、项目本身的webconfig 在<system.web>字段下 <httpRuntime targetFramework"4.5" requestLengthDiskThreshold"256" maxRequestLength"1000000000" executionTimeout"120"/> 2、找到C:\Windows\System32\inetsrv\confi…

七、文章管理页面及功能实现《iVX低代码/无代码个人博客制作》

注&#xff1a;iVX也有免费直播课《第八期直播课》 一、文章管理页页面制作 文章管理页的基本结构与首页类似&#xff0c;我们复制一个首页&#xff0c;并且重命名首页的名称为文章管理页&#xff1a; 我们接着删除如下图所框选部分内容&#xff1a; 接着重命名导航为内容…

【ArcGIS风暴】ArcGIS快捷键大全

使用快捷键能提高工作效率,本文总结了ArcGIS快捷键大全。当然了,为了个性化定制,也可以在ArcGIS中自定义快捷键。 扩展阅读: 【ArcGIS微课1000例】0015:ArcGIS如何创建/自定义快捷键? 文章目录 1. 访问 ArcMap 菜单命令2. 窗口操纵3. 刷新或暂停地图绘制4. 通过拖放进行…

.net core 抛异常对性能影响的求证之路

一、前言在.net 社区中曾经听到过很多关于大量抛异常会影响性能这样的结论&#xff0c;心中一直就存在各种疑问。项目中使用自定义异常来处理业务很爽&#xff0c;但是又担心大量抛业务异常存在性能问题。查阅了各种文档&#xff0c;微软官方对性能优化这一块也不建议使用过多的…

Android Bootloader LittleKernel的两篇文章 【转】

转自&#xff1a;http://blog.csdn.net/loongembedded/article/details/41747523 2014-12-05 14:37 3599人阅读 评论(2) 收藏 举报分类&#xff1a;Android Bootloader&#xff08;68&#xff09; Android 开发之 ---- bootloader &#xff08;LK&#xff09; LK是什么 LK 是 L…

一、首页第一个首页栏制作【仿淘票票系统前后端完全制作(除支付外)】

首页一共分为3个页面&#xff0c;分别是首页&#xff1a; 影院&#xff1a; 我的&#xff1a; 一、标题头制作 首先我们新建一个 web 相对应用&#xff0c;随后点击前台&#xff0c;在前台新建一个页面&#xff1a; 接着给予这个页面一个背景色&#xff1a; 为了使页面…

C# 11 更加实用的 nameof

C# 11 更加实用的 nameofIntro从 C# 6.0 开始&#xff0c;我们可以开始使用 nameof 来引用参数名称&#xff0c;在可能使用 nameof 的地方&#xff0c;一般都推荐使用以便于重构时的自动更新&#xff0c;在之前的 C# 版本中&#xff0c;如果想要在方法参数中或者方法 attribute…