隐式类型转化和显式类型转化

隐式类型转换

系统自动进行,不需要程序开发人员介入

int m = 3 + 45.6;//把小数部分截掉也属于隐式类型转换的一种行为
double n = 3 + 45.6;

显示类型转换(强制类型转换)

int k = 5 % (int)3.2;//语法错误,要进行强转后就OK,这里是c语言风格强制类型转换
int k= 5 %int(3.2);//函数风格的强制类型转换,结果一样 (其实一样是C语言的类型转换)

显式类型转换

C++强制类型转换分为4种:我们现在写的程序应该使用C++风格的强制类型转换

4种强制类型转换,分别用于不同的目的。每一个都又有一个不同的名字,更好的类型检查机制

a) static_cast

b)dynamic_cast

c) const_cast

d)reinterpret_cast

这四个强制类型转化都被称呼为“命名的强制类型转换(因为它们每一个都有一个名字并且名字各不相同)”

通用形式: 强制类型转换名 <type> (express);

强制类型转换名,是上边的a,b,c,d四个名字之一

type: 转换的目标类型

express: 你要转换的值(你要转换的是谁)

a) static_cast :静态转换

大家就理解成“正常转换”,编译的时候会进行类型准换的检查,代码中要保证转换的安全性和正确性,

static_cast含义跟c语言中的强制类型转换这种感觉差不多

c风格的强制类型转换,以及编译器能够进行的隐式类型转换,都可以用static_cast类显示完成

相关类型转换,比如整形和实型之间的转换

double f = 100.34f
int i = (int)f;
int i2 = static_cast<int>(f);  //c++风格的类型转换

b)后续学习类的时候子类转成父类类型(继承关系),也能用这个static_cast转

class A {}//父类
class B : public A{};//创建一个子类,继承一个父类
B b;//B类生成一个b对象
A a = static_cast<A>(b); // 把子类转成父类的对象
//B b = static_cast<B>(a);不行,不能把父类转换成子类,因为子类大于等于父类

c) void* 与其他类型指针之间的转换,void* 无类型指针:可以指向任何类型(万能指针);

int i = 10;
int *p = &i;
void *q = static_cast<void*>(p);  // int* 转成void*
int *db = static_cast<int*>(q);

不可用于:

a) 一般不能用于指针类型之间的转换比如int * 转double , float * 转double等等(看编译器报不报错就知道)

double f = 100.0f;
double *pf = &f;
//int *i = static_cast<int*>(pf);//不可以
//float *fd = static_cast<int*>(pf);//不可以
//float *fd = static_cast<float *>(pf);//不可以

b)dynamic_cast

主要用于运行时类型识别和检查,主要用来父类和子类之间转换用的(父类型指针指向子类型对象,然后用dynamic_cast把父类型往子指针类型转)往后第三章第十节详细讲

c) const_cast : 去除指针或者引用的const属性

该转化能够将const性质转换掉

编译时就会进行类型转换

const int ai = 90;
//int ai2 = const_cast<int>(ai);//不行,const_cast只能去除指针或者引用的const
const int *pai = &ai;
int * pai2 = const_cast<int*>(pai);//语法正确
*pai2 = 120;//上面刚才还是const,现在改变成可写,虽然语法上没错,但是这种写值行为是属于一种未定义未定义行为,大家不要这么干(有可能写进去,也可能写不进去)
cout << ai <<endl;//90,出现怪异现象,所以不要出现上面这种写值行为
//除非本来不是常量,后边改成改成常量,再用const_cast改成非常量,这时是可以写值的
cout << *pai <<endl;//120


const int ai = 90;
int *pai = (int *)&ai;
*pai = 120;//未定义行为,不要这么干

d) reinterpret_cast: 编译时就会进行类型转换的检查

重新解读。(将操作数内容解释为另一种不同的类型,能把操作数的类型都转了)(不要轻易用这种转换)被认为是危险的类型转换

使用时知道自己在干什么就可以

处理无关类型的转换,也就是两个转换类型之间没有什么关系,可以乱转,自由转,怎么转都行,很随意

reinterpret_cast只要好好利用,合乎规则的用,不要乱用,其实是很好用的

常用如下两种转换:

将一个整形(地址)转换成指针;一种类型指针转换成另一种类型指针,按照转换后的内容重新解释内存中内容;

也可以将一个指针类转换成一个整型

int i = 0;
int *pi = &i;
int *p2 = reinterpret_cast<int*>(&i);
char *pc = reinterpret_cast<char*>(pi);//随便转


int iv1 = 100;
long long lv1 = 8898899400;//8字节的, 16进制: 2  126A  6DC8
int *piv1 = (int*)iv1;//c语言风格的; 0x00000064
int *piv2 = reinterpret_cast<int*>(iv1);//0x00000064
piv2 = reinterpret_cast<int*>(lv1);//0x 126a 6dc8   把前边的2丢了,因为piv2是4字节
long long ne = reinterpret_cast<long long>(piv2)//指针类型转整形  308964808 = 126A 6DC8
    

总结:

(1)强制类型转换都不建议使用,强制类型转换能够抑制编译器报错。

(2)学习目的是认识这些类型转化符,方便大家阅读别人代码

(3)资料说:reinterpret_cast危险,使用const_cast意味着设计缺陷

(4)如果实在需要用到类型转换,不要再使用c语言风格的类型转换,而使用c++风格的类型转化

(5)一般static_cast 和 reinterpret _cast就能够很好的取代c语言风格的类型转换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值