c++ static_cast dynamic_cast const_cast reinterpert_cast看这一篇就够了
一.隐式转换,系统自动进行,不需要程序员介入。
int m = 3 + 45.6;//int->double->int.把小数部分截断。
double n = 3 + 45.6;//int->double
二.显示类型转换
int k = 5 % 3.2;//语法错误
int k = 5 % (int)3.2;*///c语言风强制类型转换。
int k = 5 % int(3.2);//函数风格的强制类型转换(c语言风格的强制类型转换)
c++强制类型转换分为4种:写程序应该使用c++风格的强制类型转换
4中强制类型转换,用于不同的目的。提供丰富的含义和功能,更好的类型机制,方便代码的编写和维护
a).static_cast
b).dynamic_cast
c).const_cast
d).reinterpert_cast
这四个强制类型转换,被称为“命名的强制类型转换”
通用形式
强制类型转换名< type>(express)
type:转换的目标类型
erpress:转换的值
2.1 static_cast 静态转换,正常转换,编译的时候进行类型转换检查。代码中保证安全性和正确性
和c语言中的强制类型转换感觉差不多
c风格强制类型转换,以及编译器能够进行饮食的类型转换,都可以用static_cast显示转换完成
a. 可用于相关类型转换。比如整型和实型之间的转换
double f = 3.14f;
int i = int(f);
int i2 = static_cast<int>(f);
b.子类转换成父类,也可以用这个,子类可以转成父类,父类不可以转成子类
class A {};
class B :public A {};
B b;
A a = static_cast<A>(b);
c. void * 于其他类型指针之间的转换。void *:无类型指针,可以指向任何指针类型(万能指针)
int i = 10;
void* q =static_cast<void*> (&i);
int* db =static_cast<int*> (q);
不可用于
a. 一般不可用于指针类型的转换,int * double * …
double f = 100.0f;
double* pf = &f;
int* i = static_cast<int> (pf);//错误
float* fd = static_cast<float> (pf);//错误
2.2 dynamic_cast.主要是父类型子类型转换用的。用来让父类指针指向子类对象,用dynamin_cast 把父类指针往子类型转
2.3 const_cast 去除指针或者引用的const属性。该转换能够将const性质去掉。功能有限,编译时进行
const int ai = 90;
int ai2 = const_cast<int> ai;//ai不是指针也不是引用,不能转
const int* pi = &ai;
int* pi2 = const_cast<int*>(pi);//语法正确
*pi2 = 120;//虽然语法没错,不要怎么写,写值行为属于未定义行为。不要这么干,有可能写进去,有可能写不进去
const int ai = 90;
int* pai = (int*)&ai;//未定义行为
int i = 10;
double d = const_cast<double> i;//错误
2.4 reinterpert_cast (重新解释)在编译的时候进行类型转换检查。处理无关类型的转换,两个转换类型之间没有什么关系。就是等于乱转。很随意。常用如如下两种转换。
a).将一个整型(地址)转换成指针,一种类型的指针转换成另一种类型指针,按照转换后的内容重新解释内存。
b).将一个指针类型转换成整型。
int i = 10;
int* pi = &i;
int* p2 = reinterpret_cast<int*>(&i);
char* pc = reinterpret_cast<char*>(pi);//出错
int i = 10;
int* pi = &i;
void* pvoid = reinterpret_cast<void*>(pi);
int* pi2 = reinterpret_cast<int*>(pvoid);//正确
被认为是种危险的转换,编译器不报错,安全性比较差。
int iv1 = 100;
long long lvl = 88000000000; //8字节,十六进制:2 126a 6dc8
int* piv1 = (int*)iv1;//c语言风格, 0x0000064
int* piv2 = reinterpret_cast<int*>(iv1);// 0x0000064
piv2 = reinterpret_cast<int*>(lvl);// 0x 126a 6dc8 把前面的2丢了,因为piv2是4字节。
long long ne = reinterpret_cast<long long> (piv2);//308246254 126a 6dc8
三 总结
- 强制类型转换,不建议使用。强制类型转换能够抑制编译器报错。
- 学习目的,认识类型转换符,方便阅读别人代码
- 资料说:reinterpret_cast很危险,使用const_cast意味着涉及缺陷。
- 如果实在需要用到类型转换,用c++风格转换。不要再使用c语言风格的转换。
- 一般static_cast 和reinterpret_cast取代c语言风格的转换.
- reinterpret_cast 合乎规则的用,其实很好用。