如:int ival = 3.35 + 3;
这里字面值3.35为double型,字面值3为int型。首先3隐式转换为double型,运算结果是6.35(double型)。接下来是初始化,初始化时又进行一步隐式转换,转换成6(int型)最后将ival初始化为6.
隐式转换
何时发生隐式转换?
·比int小的整形值先提升为较大的整形值
·条件表达式中,bool与非bool间转换
·初始化时,初始值转换为变量值(构造函数)。赋值时,右侧类型转换为左侧类型(转换操作符)。
·若算数运算或关系运算中类型不一,则转换成同一类型。
·函数调用时。
算数转换
首先:整型提升。对于bool, char、signed char、unsigned char、short、 unsigned short等类型,只要他们的值能存在int里,他们就会被提升成int;否则,被提升成unsigned int。提升位宽取int,unsigned int, long, unsigned long, long long, unsigned long long中的最小一种类型。
第二步:统一类型。
·判断类型是否一致,一致则直接计算;不一致则小类型调整成大类型。(这里的大小类型依赖于机器,如unsigned int与long,具体谁大谁小,视机型而定);
如:这里假定unsigned short < int ; unsigned int < long
char | unsigned char | short | unsigned short | int | unsigned int | long | unsigned long | |
char | i+i | i+i | i+i | i+i | i+i | i+ui ui+ui | i+l l+l | i+ul ul+ul |
unsigned char | i+i | i+i | i+i | i+i | i+i | i+ui ui+ui | i+l l+l | i+ul ul+ul |
short | i+i | i+i | i+i | i+i | i+i | i+ui ui+ui | i+l l+l | i+ul ul+ul |
unsigned short | i+i | i+i | i+i | i+i | i+i | i+ui ui+ui | i+l l+l | i+ul ul+ul |
int | i+i | i+i | i+i | i+i | i+i | i+ui ui+ui | i+l l+l | i+ul ul+ul |
unsigned int | ui+i ui+ui | ui+i ui+ui | ui+i ui+ui | ui+i ui+ui | ui+i ui+ui | ui+ui | ui+l l+l | ui+ul ul+u; |
long | l+i l+l | l+i l+l | l+i l+l | l+i l+l | l+i l+l | l+ui l+l | l+l | l+ul ul+ul |
unsigned long | ul+i ul+ul | ul+i ul+ul | ul+i ul+ul | ul+i ul+ul | ul+i ul+ul | ul+ui ul+ul | ul+l ul+ul | ul+ul |
其他类型转换
·数组转换成指针。int [10]; int*p = a;
·指针转换。0, nullptr, bool,
·转换成const。如const引用,指向const的指针。
·类类型定义的转换。自定义转换类型(如单参构造函数,类型转换运算符),不过不能一次提出多个转换请求。应尽量避免隐式转换。
显示转换
又称强制类型转换。建议尽量避免强制类型转换。
c++提供了四种强转表达式
static_cast、dynamic_cast、const_cast、reinterpret_cast。
static_cast
如内建大类型转小类型:double->int;或者指针转换<A*> ---> <B*>
const_cast
只能改变运算对象的底层const (注意区分顶层const与底层const)
reinterpret_cast
底层位模式上的重新解释。
dynamic_cast
有继承关系的指针间转换。
这四种转换,除static能转换基本类型外,其余都是针对指针类型。