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 father
5 {
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 long
8 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

c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast的更多相关文章

  1. C++雾中风景11:厘清C++类型转换(static_cast,dynamic_cast,reinterpret_cast,const_cast)

    C++是一门弱类型的语言,提供了许多复杂和灵巧类型转换的方式.笔者之前写的Python与Go都是强类型的语言,对这种弱类型的设计实在是接受无力啊~~ ( 生活所迫,工作还得写C++啊~~)C++语言提 ...

  2. C++ static_cast dynamic_cast reinterpret_cast const_cast转换

    static_cast <type-id> ( expression ) 和C风格的类型转换相似,可以转换一个指针到基类,或者派生类.不做Run-time类型检查,这样转换并不总是安全的. ...

  3. static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较

    隐式转换(implicit conversion) ; int b; b=a; short是两字节,int是四字节,由short型转成int型是宽化转换(bit位数增多),编译器没有warning,如 ...

  4. static_cast, dynamic_cast, reinterpret_cast, const_cast的区别

    static_cast最像C风格的强制转换,很多时候都需要程序员自身去判断转换是否安全.但是相对C风格的强制转换,在无关类的类指针之间转换上,有安全性的提升. dynamic_cast是运行时的转换吧 ...

  5. c++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast

    c++强制类型转换:dynamic_cast.const_cast .static_cast.reinterpret_cast 博客分类: C/C++ CC++C#编程数据结构  dynamic_ca ...

  6. reinterpret_cast,static_cast, dynamic_cast,const_cast的运用分析

    reinterpret_cast(重新解释类型转换) reinterpret_cast 最famous的特性就是什么都可以,转换任意的类型,包括C++所有通用类型,所以也最不安全 应用 整形和指针之间 ...

  7. 你也许还不知道const_cast,static_cast,dynamic_cast,reinterpret_cast的区别吧?

    [QQ群: 189191838,对算法和C++感兴趣可以进来]       开篇立意: C++中各种转换令人眼花缭乱,看似差不多,实际差很多,而且在当今时间,做一个"差不多先生"其 ...

  8. C++中四种类型转换方式(ynamic_cast,const_cast,static_cast,reinterpret_cast)

    Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意? A:转换的含义是通过改变一个变量的类型为别的类型从而 ...

  9. C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

    1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 ...

随机推荐

  1. iOS 分享至友盟分享

    iOS 友盟分享 这个主要是提到如何通过友盟去自定义分享的步骤: 一.肯定要去友盟官网下载最新的SDK包,然后将SDK导入到你的工程文件夹里面去: 二.注册友盟账号,将你的APP添加到你的账号里面然后 ...

  2. Echarts_1:水平柱体

    Echarts:http://echarts.baidu.com/index.html 这下面是我自己总结的一些配置注释,分享~ 效果图: 小白小白小白小白小白小白小白小白小白小白小白小白小白小白小白 ...

  3. road习题(二)

    答案:[C] 解析:2 8 原则,考虑的是最高峰,所以安装12小时算 ,80%的 PV 也就是访问都是在 早上6点到下午6点这12个小时里,晚上6点到早上6点的PV总量是40000 ,服务器台数为3, ...

  4. Python 启动本地服务

    在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer,我们可以很简单的使用  python -m SimpleHTTPServ ...

  5. html中css、div命名规范

    html中css.div命名规范 1.类class的命名规范示例 头:header 内容:content/container 尾:footer 导航:nav 侧栏:sidebar 栏目:column ...

  6. CentOS 安装 lamp(转)

    一般情况下,安装的都是最新的正式版,除非你有特殊需求,要安装指定的版本,本文暂不讨论.从最基础的开始,一点点完成一个可用的 Linux 主机.这里就开始介绍如何在 CentOS 6.0 上安装 LAM ...

  7. ubuntu-kylin16.04搭建lamp环境。

    首先下载安装apache2 输入:sudo apt-get install apache2 安装完毕后,在浏览器中输入:localhost 显示如下图,说明安装正确. 紧接着安装php7.0 输入:s ...

  8. 十天精通CSS3学习笔记 part1

    http://www.imooc.com/learn/33 第1章 初识CSS3 什么是CSS3? CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能. 目前主 ...

  9. 通过图片对比带给你不一样的KMP算法体验

    KMP 算法,俗称“看毛片”算法,是字符串匹配中的很强大的一个算法,不过,对于初学者来说,要弄懂它确实不易. 笔者认为,KMP 算法之所以难懂,很大一部分原因是很多实现的方法在一些细节的差异.体现在几 ...

  10. applicationContext配置文件中的属性说明

    lazy-init:设置只对scop属性为singleton的bean起作用. 1.true:延迟加载:这时在第一次向容器通过getBean索取bean时实例化的. 2.false:表示spring启 ...