目录
一,隐式类型转换
C/C++都有,包括赋值语句转换、初始化时的转换、表达式中的转换、传参时的转换
1,C语言隐式类型转换
1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned int(如果short与int的大小相同,unsigned short就比int大。这种情况下,unsigned short会被转换成unsigned int)。
在K&R那时的C中,float会被自动转换成double(目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级。
2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。
3.类型的级别从高至低依次是long double、double、float、unsigned long long、long long、unsigned long、long、unsigned int、int。
例外的情况是,当long 和 int 的大小相同时,unsigned int比long的级别高。
4.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级。
5.当作为函数参数传递时,char和short被转换成int,float被转换成double
2,C++隐式类型转换
Ranking of implicit conversion sequences
1) Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, function pointer conversion, (since C++17) user-defined conversion of class type to the same class
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base
精确匹配、提升、转换 三种隐式类型转换(包括里面的各小项)优先级依次降低。
由构造函数完成的隐式转换:
class A {
public:
A(int x)
{
this->x = x * x;
}
int x;
};
int f(A a)
{
return a.x + 1;
}
int main()
{
cout << f(3) << " ";
return 0;
}
输出10
相当于:
int main()
{
A b = 3;
cout << f(b) << " ";
return 0;
}
而如果是这样:
int f(A a)
{
return a.x + 1;
}
int f(double a)
{
return a + 2;
}
int main()
{
cout << f(3) << " ";
return 0;
}
则输出5,因为int转double的优先级高一些。
二,强制类型转换
C/C++都有,写法略有区别
C风格:(int)x
C++风格:int(x)
by the way, (int)(x) 这种写法也是OK的
三,类型转换去const
c语言的const入参毫无约束力:
int f(const int*pp)
{
int *p=pp;
*p=3;
return 0;
}
C++要稍微好一点:
int f(const int*pp)
{
int *p=(int *)pp;
*p=3;
return 0;
}
四,强制类型转换运算符
C语言里面只有(int)这种形式的强制类型转换运算符,没有专用的强制类型转换运算符。
C++有4个专用的强制类型转换运算符:
dynamic_cast
const_cast
static_cast
reinterpret_cast
发明这4个运算符,是为了严格限制使用场景,使得用法更规范,避免一些不容易发现的错误。
(1)dynamic_cast
(2)const_cast
(3)static_cast
(4)reinterpret_cast