新型的类型转换(九)
我们之前在 C 语言进行类型转换是强制类型转换的,这样极易出 bug,还不易查找。格式如下:(Type)(Experssion) 或 Type(Experssion),我们来看个示例代码,看看 C 语言中的强制类型转换
#include<stdio.h>typedefvoid(PF)(int);structPoint{intx;inty;};intmain(intargc,char*argv[]){intv=0x12345;PF*pf=(PF*)v;charc=char(v);Point*p=(Point*)v;pf(5);printf("p->x=%d\n",p->x);printf("p->y=%d\n",p->y);return0;}
编译结果如下
我们看到直接运行段错误,但是它编译是通过的,因此我们如果在大型的项目中是难以查找 bug 的。
在 C 方式的强制类型转换的过程中,它存在的问题:a> 过于粗暴:任意类型之间都可以进行转换,编译器很难判断其正确性;b> 难于定位:在源码中无法快速定位所有使用强制类型转换的语句。那么强制类型转换在实际工程中是很难完全避免的!如何进行更加安全可靠的转换呢?在 C++ 中出现了新式类型转换,C++ 将强制类型转换分为 4 中不同的类型:a> static_cast;b> const_cast;c> dynamic_cast;d> reinterpret_cast;用法是:xxx_cast<Type>(Expression)。下来我们分别来讲下这四种新式类型转换的特点及要求
A、static_cast 强制类型转换
用于基本类型间的转换;不能用于基本类型指针间的转换;用于有继承关系类对象之间的转换和类指针之间的转换。
B、const_cast 强制类型转换
用于去除变量的只读属性;强制转换的目标类型必须是指针或引用。
C、reinterpret_cast 强制类型转换
用于指针类型间的强制转换;用于整数和指针类型间的强制转换。
D、dynamic_cast 强制类型转换
用于有继承关系的类指针间的转换;用于有交叉关系的类指针间的转换;具有类型检查的功能;需要虚函数的支持。
关于上面讲到的有些概念,我们会在后面进行详细的介绍,下来我们以代码为例进行分析
#include<stdio.h>voidstatic_cast_demo(){inti=0x12345;charc='c';int*pi=&i;char*pc=&c;c=static_cast<char>(i);pc=static_cast<char*>(pi);//error}voidconst_cast_demo(){constint&j=1;int&k=const_cast<int&>(j);constintx=2;int&y=const_cast<int&>(x);intz=const_cast<int>(x);//errork=5;printf("k=%d\n",k);printf("j=%d\n",j);y=8;printf("x=%d\n",x);printf("y=%d\n",y);printf("&x=%p\n",&x);printf("&y=%p\n",&y);}voidreinterpret_cast_demo(){inti=0;charc='c';int*pi=&i;char*pc=&c;pc=reinterpret_cast<char*>(pi);pi=reinterpret_cast<int*>(pc);pi=reinterpret_cast<int*>(i);c=reinterpret_cast<char>(i);//error}voiddynamic_cast_demo(){inti=0;int*pi=&i;char*pc=dynamic_cast<char*>(pi);//error}intmain(){static_cast_demo();const_cast_demo();reinterpret_cast_demo();dynamic_cast_demo();return0;}
我们来分析下这个代码,在 static_cast_demo 中,static_cast 不能用于指针间的转换,所以第 11 行会报错。在 const_cast_demo 中,第 16 行定义了一个具有只读属性的变量 j,我们还是可以通过 const_cast 来改变它的属性的。第 19 行定义了一个真正意义上的常量,它会进入到符号表中,但在栈上会为它分配 4 个字节的空间,所以第 20 行的也会成功。const_cast 强制转换的目标类型必须是指针或引用,所以第 22 行会报错。第 26 、 27 行会打印出 5、5;第 31 - 34 会打印出 2、8、后面两个地址是一样的。在 reinterpret_cast_demo 中,reinterpret_cast 用于指针类型间及整数和指针类型间的强制转换,所以第 47 行会报错。在 dynamic_cast_demo 中,第 54 行会报错。我们来看看编译结果
我们分别注释掉这几行,再来编译,看看结果是否如我们所分析的那样
我们看到和我们所分析的是一致的。通过对强制类型转换的学习,总结如下:1、C 方式的强制类型转换:a> 过于粗暴。 b> 潜在的问题不易被发现。 c> 不易在代码中定位;2、新式类型转换以 C++ 关键字的方式出现:a> 编译器能帮助检查潜在的问题。 b> 非常方便的在代码中定位。 c> 支持动态类型识别(dynamic_cast)。
欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。