c++知识细节-隐式类型转换/显示类型转换
隐式类型转换
系统自动转换,不需要开发人员介入
int m = 3 + 45.6 //float->int;48.60000->48 小数部分被截掉
double n = 3 + 45.6 //48.6
显示类型转换(强制类型转换)
int k = 5 % 3.2; //语法错误,%两边必须是整形
//此时可以强转
int k = 5 % (int)3.2; //ok,c语言风格的强转
int k = 5 % int(3.2); //ok,函数风格的强转,也是c语言风格
- c++风格的强制类型转换,共有4种,分别用于不同的目的,写c++代码最好用这些.
static_cast
,dynamic_cast
,const_cast
,reinterpret_cast
都被称为命名的强制类型转换.
通用形式:
强制类型转换名<type>(express)
type: 转换的目标类型
express: 你要转换的是谁 - static_cast
静态转换,可以理解成正常转换,编译的时候就会进行类型转换的检查.和c语言中的强制类型转换的感觉差不多.
可用于:
a) 相关类型转换,比如整形和实型之间的转换
double f = 100.34f;
int i = (int)f; //c风格的
int i2 = static_cast<int>(f); //c++风格的类型转换
b) 子类转成父类类型(继承关系)
class A{}
class B: public A{};
B b;
A a = static_cast<A>(b); //把子类转成父类对象
c) void *与其他类型指针之间的转换,void *是无类型指针,也叫万能指针,可以指向任何类型.
int i = 10;
int *p = &i;
//int * 转为 void *
void *q = p;
//void * 转为 int*
int *db = q; //报错
int *db = static_cast<int *>(q);
不可用于:
a) 不可用于指针类型之间的转换,如int * 转double ,float 转double*等
double f = 100.0f;
float *pf = static_cast<float *>(f); //报错
-
dynamic_cast
主要用于运行时的类型识别和检查,主要用父类型和子类型之间的转换(父类型指针指向子类型对象,然后用dynamic_cast把父指针类型往子指针类型转).暂不仔细描述,后续父子继承章节再说. -
const_cast
用于去除指针或者引用的const属性.编译是就会进行的类型转换.
const int ai = 90;
int ai2 = const_cast<int>(ai); //报错,因为ai既不是指针也不是引用
const int *pai = &ai;
int *pai2 = const_cast<int *>(pai); //语法正确
*pai2 = 120;
//不要这么做,这种写值行为属于一种未定义行为,虽然不报错,但是不一定能写进去,结果不固定,甚至加断点和实际结果都不同,可能出现怪异的结果.
- reinterpret_cast
重新解释.将操作的内容解释为另一种不同的类型,编译时就会进行.
用于处理无关类型的转换,很随意,自由转换.
常用于以下两种转换:
a) 将一个整形(地址)转换为指针;一种类型的指针转换为另一种类型的指针.
按照转换后的内容重新解释内存中的内容
b) 将一个指针类型转换为一个整型
int i = 10;
int *pi = &i;
char *p2 = reinterpret_cast<char*>(pi); //转换后编程用char来解释这块内存了,10变成了\n.
被认为是一种危险的类型转换,怎么转都不报错,在使用前一定要搞清楚自己在干什么,转换的目的是什么
int iv1 = 100;
long long lv1 = 8898899400; //8字节. 十六进制: 2 126A 6DC8
int * piv1 = (int *)iv1; //c语言风格,整型转地址
int * piv12 = reinterpret_cast<int *> (iv1); //0x00000064(???)
int * plv1 = reinterpret_cast<int *>(lv1); //ox126A6DC8,因为plv1是4个字节的
long long ne = reinterpret_cast<long long>(plv1); //指针类型转整型 =308964808 = 126A 6DC8
- 总结
(1)强制类型转换不建议使用,强制类型转换能够抑制编译器报错.
(2)学习目的:学习类型转换符,阅读代码是能看懂是什么.
(3)资料说:reinterpret_cast危险,const_cast意味着设计缺陷
(4)实在要用,不要再使用c语言风格的类型转换了,而用c++风格的.
(5)一般static_cast和reinterpret_cast就能很好地取代c语言风格的类型转换.