类型转换:static_cast、reinterpret_cast等
一、隐式类型转换
系统自动进行,不需要程序开发人员介入。
int m = 3 + 45.6;// 48 把小数部分截掉,也属于隐式类型转换的一部分
double b = 3 + 45.6; // 48.6
二、显示类型转换(强制类型转换)
int key = 5 % 3.2; // 语法错误 int k = 5 % (int)3.2; // 强制转换为3,C语言风格的类型转换 int k1 = 5 % int(3.2); // 函数风格的强制类型转换
C++类型强制类型转换分为4种:
这四种强制类型转换被称为命名的强制类型转换;目的是为了提供更加丰富的含义和功能,更好的类型检查机制。
通用形式:强制类型转换名<type>(express)
(1)static_cast:静态转换,编译的时候就会进行类型转换的检查
代码中要保证类型转换的安全性与正确性,含义与C语言的强制类型转换意义差不多。C风格的强制类型转换以及编译器能够进行的隐式类型转换,都可以用static_cast类型显示完成。
可用于:
(a)相关类型转换,比如整型和实型之间的转换
double f = 100.43f; int i = (int)f; // C风格的 int i2 = static_cast<int>(f); // C++风格的强制类型转换 显示
(b)子类转换为父类的时候(继承关系),也可以用static_cast
calss A{}; class B : public A{}; // 公有继承 B b; A a = static_cast<A>(b);// 将子类转换为父类
(c)void *与其他的类型指针之间的转换,void *无类型指针,可以指向任何类型的指针(万能指针)
int i = 10; int *p = &i; void *q = static_cast<void *>(p); // int *转换为void * int *dq = static_cast<int *>(q); // 将void *转换回int *
一般不能用于:
(a)一般不能用于指针类型之间的转换比如int * 转double *,float *转 double*等等
double f = 100.0f; double *pf = &f; // int *if = static_cast<int *>(pf); // 不可以 // float *if = static_cast< float *>(pf); // 不可以
(2)dynamic_cast
主要应用于运行时类型识别与检查。主要用来父类型和子类型之间转换用(父类型指针指向子类型对象,然后用dynamic_cast把父指针类型转换为子指针类型)
(3)const_cast
去除指针或引用的const属性,该指针能将const性质转换掉,编译时类型转换。
cons tint ai = 90; //int ai2 = const_cast<int>(ai); // ai不是指针或引用,不能转换 const int *pai = &ai; const int *pai2 = const_cast<int *>(pai); // 语法正确 *pai2 = 120; // 这种写值行为,属于一种未定义行为,尽量不要这么写 cout <<ai << endl; // 90 cout << *pai << endl; // 120
cons tint ai = 90; int *pai2 = (int *)&ai; // 语法正确 *pai2 = 120; // 这种写值行为,属于一种未定义行为,尽量不要这么写 cout << ai << endl; // 90 cout << *pai2 << endl; // 120
(4)reinterpret_cast
编译的时候就会进行类型转换的检查,翻译,重新解释
将操作数内容解释为另一种不同的类型。
处理无关系的转换,也就是两个类型转换之间没有什么关系;就等于什么都可以转换。
(a)将一个整型(地址)转换为指针,一种类型指针转换为另一种类指针,按照转换后的内容重新解释内存中的内容。
(b)也可以从一个指针转换为整型
int i = 10; int *p = &i; int *p2 = reinterpret_cast<int *>(&i); char *pc = reineterpret_cast<char *>(pi); int I = 10; int *p = &I; void *pvoid = reinterpret_cast<void *>(p); int *p1 = reinterpret_cast<int *>(pvoid); // 被认为是危险的类型转换
int iv1 = 100; long long lv1 = 8898899400;// 88亿 十六字节:2 126A 6DC8 int *piv1 = (int *)iv1; // C语言风格 //0X00000064 int *piv2 = reinterpret_cast<int *>(iv1);//0X00000064 piv2 = reinterpret_cast<int *>(lv1); // OX126A 6DC8 把前面的2丢了,因为piv2是4字节的 long long ne = reinterpret_cast<long long>(piv2); // 指针类型转long long // 308964808 十六进制:126A 6DC8
三、总结
(1)强制类型转换,不建议使用;强制类型转换能够抑制编译器报错。
(2)了解类型转换符,方便阅读别人代码。