4.11 类型转换

本文详细介绍了C++中的隐式类型转换,包括整型提升、算术转换和其他情况,如数组和指针转换。同时,讨论了显式类型转换,如static_cast、const_cast和reinterpret_cast的使用,强调了过度使用强制类型转换的风险。
摘要由CSDN通过智能技术生成

如果两种类型可以相互转换(conversion),那么他们是关联的

 int ival = 3.541+3;//编译器可能会警告运算损失了精度

会将类型转换后再执行,称为 隐式转换(implicit conversion)

算数类型的隐式转换会尽可能避免失去精度,如上述的例子 3会被转换成double,得到的结果是double并把double赋给int

何时发生隐式类型转换

  • 大多数表达式中,比int类型小的整型值首先提升为较大的整数类型
  • 在条件中,非布尔值转换成布尔类型
  • 在初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型
  • 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型
  • 函数调用时也会发生类型转换

4.11.1 算术转换

算术转换(arithmetic conversion)是把一种算术类型转换成另外一种算术类型

整型提升

整型提升(integral promotion)负责把小整数类型转换成较大的整数类型。

对于 bool,char,signed char, unsigned char, short 和 unsigned short等类型来说,只要它们所有可能的值都能存在 int 里,他们就会提升成 int 类型; 否则,提升成unsigned int 类型。

如 false提升成 0,true提升成1

较大的char类型(wchar_t,char16_t,char32_t)被提升成int ,uunsigned int , long ,unsigned long ,

 long long和 unsigned long long 中最小的一个

无符号类型的运算对象

如果一个运算对象是无符号类型,另一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,带符号类型会转换成无符号的(为什么不把无符号转成带符号?因为无符号要>=带符号类型)

如果是带符号类型大于无符号类型,此时依赖于机器,如果无符号所有值都能存在带符号类型中,则无符号类型的运算对象转换成带符号类型,如果不能则反之

 

理解算术转换

(一些算术转换)

P143 略

 

4.11.2 其他隐式类型转换

数组转换成指针

:在大多数用到数组的表达式中,数组自动转换成指向数组首元素的指针

当数组被用作 decltype 关键字的参数,或者作为 取地址符(&),sizeof即typeid等运算符的运算对象时,

上述转换不会发生。如果用一个引用来初始化数组,上述转化也不会发生

 

指针的转化

:C++规定了其他的指针转换方式

包括常量整数值0或者字面值nullptr能转换成任意指针类型;

指向任意非常量的指针能转换成 void*

指向任意对象的指针转换成 const void*

有继承类关系中还有一种

 

转换成布尔类型:

存在一种从算术类型或指针类型向布尔类型

 

转换成常量:

允许将指向非常量类型的指针转换成指向相应的常量类型的指针,对于引用也是这样

如果说T是一种类型,我们就能将指向T的指针或引用转换成指向 const T

 int I;

 const int &j = I; //非常量转换成const int的引用

 const int *p = &I;//非常量的地址转换成const大的地址

 

类类型定义的转换:

 string s , t ="A string"; //字符串字面值转换成string类型

 while(cin>>s) ; //while 的条件部分把cin转换成布尔值

 

 

4.11.3 显示转换

强制类型转换(cast)

warning:虽然有时不得不使用强制类型转换,但这种方法本质上是非常危险的。

 

命名的强制类型转换

形式如下

 cast-name<type>(expression);

 type是转换的目标类型而expression是要转换的值

如果type是引用类型,则结果是左值

 cast-name是 static_cast , dynamic_cast, const_cast , reinterpret_cast 其中的一种

 static_cast

 具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast

 double slope = static_cast<double>(j) / I;

 static_cast对强制转换为原来的类型时(找回void*)

 void* p = &d;

 double *dp = static_cast<double*>(p);

 应保证指针的值保持不变,

 强制类型的结果将于原始的地址值相等,因此我们必须确保转换后所得的类型就是指针所指的类型。

类型一旦不符将产生未定义的后果

 const_cast

 const_cast 只能改变运算对象的底层const

 const char *pc;

 char *p = const_cast<char*>(pc);//正确:但是通过p写值未定义

 const_cast 只能去掉const性质(cast away the const),不能改写对象类型;

 const_cast常常用于有函数重载的上下文中

 reinterpret_cast

 reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释

warning:reinterpret_cast 本质上依赖于机器。想要更安全的使用reinterpret_cast必须对设计的类型和编译器实现转换的过程都非常了解

建议:避免强制类型转换

 

旧式类型的强制类型转换

在早期c++语言中,显示强制转换包含两种形式

 type(expr);   //韩叔叔形式的强制类型转换

 (type) expr; //c语言形式的强制类型转换

在某处执行旧式的强制类型转换,如果换成const_cast,static_cast也合法,则其行为与对应命名转换一致

 如果替换后不合法,则与 reinterpret_cast类似的功能的效果一样

warning: 与命名的强制类型转换相比,旧式的强制类型转换从表现形式上来说不那么清晰,很难被追踪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值