C++中旧式的强制类型转换主要是通过用圆括号来将类型括起来实现的:
int a = 3; double b = (int)a;
但是这中强制转换的缺点就是转换的可视性是比较差的,难以跟踪错误的转换,在C++中后来
为了解决这种问题就引入了命名的强制类型转换符。
二、命名的强制类型转换符
在C++中命名强制类型转换符一共有一下几种:static_cast、dynamic_cast、const_cast、reinterpret_cast
A: dynamic_cast()转换
该种转换主要特点是支持运行时识别指针或引用所指向的对象。在C++中dynamic_cast的最主要作用
就是将基类类型的指针或引用安全地转换为派生类类型的指针或引用。但是请注意:一、dynamic_cast作用的
指针必须为有效指针;二、作用的该基类型必须带有一个或一个以上的虚函数,否则会转换出错。因为只有是
含有虚函数的基类指针时,编译器才能够静态地插入获取到该指针所指对象地址中的VPTR指针,并且通过VPTR
指针在VTABLE(虚函数表)中获取到该地址对象的实际类型,而且没有虚函数的类后派生类中是不存在VPTR机制的。
For Example: #include<iostream> using namespace std; class base{ public : int ma; int mb; virtual ~base() //基类必须要有一个虚函数,无论是否为虚析构函数 { } }; class de :public base { public: int mc; }; int main() { base * pb; de d; d.ma = 1; d.mb = 2; d.mc = 3; pb = &d; de *s = dynamic_cast<de *>(pb);//运行时的类型转换 cout<<"ma:"<<s->ma<<endl; cout<<"mb:"<<s->mb<<endl; cout<<"mc:"<<s->mc<<endl; /*输出: ma:1 mb:2 mc:3 请按任意键继续. . . */ return 0; }
B: const_cast()转换
const_cast()转换是一种去掉const性质的转换,即将一个“指向const对象的指针或引用”转化成一个“指向非const对象”。
使用注意:
a:C++中对于const性质的转换必须且只能用const_cast函数进行,没有其他的任何方法。
b:const_cast转换只能被用于const性质的去掉转换,不能用于其他任何别的类型的转化,否则 都会出错。
c:const_cast<>()转换的作用对象只能是指向const对象的指针,对const对象的引用。而不能更改一个变量
的基础类型。
For Example: const int a = 2; const int * p = &a; //const_cast转换 int* b = const_cast<int *>(p); (*b) = 5;
C:static_cast()转换
static_cast<>()转换是C++中一种强大的类型转换,编译器隐式执行的任何类型转换都能用static_cast显式的完成。
其存在的主要作用有以下几点:
1:当把所有的隐式转换改编成static_cast的显式转换时,不仅将会消除编译器的警告消息,而且将会使转换的
透明度提升,即会更易于跟踪错误的转换代码。
2:对于编译器不存在的转换,用static_cast进行显示转换时一般也是不允许的,但是特例确实确实指针类型的转换,
即使用 static_cast可以重新将void*类型的指针转换成别的指针类型,也就是说可以找回void*中所指向的值了。
For Example: //编译器已经存在的类型转换 char c ; double dou = 0.08; c = static_cast<char>(dou); //void*类型的转换 void * vp; int * ip; int i = 666; ip = &i; vp = ip; int * ip2 = static_cast<int *>(vp); cout<<(*ip2)<<endl;
D: reinterpret_cast()转换
reinterpret_cast转换是基于一种位模式的转换,也就是说从位模式对一个数据的类型进行了另外一种解释。(
即可以将一种类型的指针直接转换成另一种类型的指针,但是转换类型后的数据不一定有意义)注意这种转换出错的风险
极大,一定要注意需要转换的类型的对象值在按位模式(也就是字节流)当按照另一种数据类型的
方法去解释时是否有实际意义,这个很重要的。
For Example: int i = 97; int * pi = &i; char * pc = reinterpret_cast<char * >(pi); cout<<(*pc)<<endl; //输出‘a’ double *pd = reinterpret_cast<double *>(pi); cout<<(*pd)<<endl;//输出-9.25596e+061 /* 注意:这里输出的-9.25596e+061,并不是乱码或随机值,而是从-9.25596e+061到97符合部分长度内的补码规则 */ unsigned * pu = reinterpret_cast<unsigned *>(pi); cout<<(*pu)<<endl;//输出97