c++-类型转换
要点
表达式合法性和语义由操作数类型决定
如果两个类型之间可以转换,则称这两类型相关
C++类型转换目标是尽可能防止精度丢失
隐式类型转换
优点
方便开发人员的使用,避免各种显式地转换
提供自然的语义,像内置类型一样,
int(1) + double(1.1)
无需额外重载,来支持多种操作符运算,重载数量与运算符线性相关!
缺点
- 不利于掌控,有些隐式转换不是想要的,出现错误时,很难定位
发生场景
当某个变量需要T2类型值,而该表达式值为T1类型,此时编译器会执行隐式类型转换。
具体场景:
当该表达式作为某个操作符(
=
,+
…)的操作数,与期望类型T2不符当该表达式作为函数调用实参,与形参类型T2不符
当作为函数返回语句时,与返回类型T2不符
当该表达式作为switch语句(T2为intergal)
当该表达式作为条件表达式(if, while, for, !, &&, ||)(T2为bool)
实现方式(自定义类型)
T2=>T1
单参数构造函数(converting constructor)
1 | T1(T2 t2); |
T1=>T2
类型转换操作符函数(Conversion Operator)
1 | operator T2&(); |
# 禁止隐式类型转换
通过explicit
关键字修饰函数,说明该函数不能被用来隐式转换,只能进行显式转换!
要点
- 条件表达式中有
singed
和’unsigned’时,singed
会转化为unsinged
(对应类型的模运算值,如1B的-1转换为255)
显式类型转换(C++风格转换)
优点:
意图更加明确,编译器可以提供更准确地检查,尽可能早地发现错误
利于代码阅读和工具检索
static_cast
编译期内
使用隐式类型转换或用户自定义转换
安全性较高,编译器进行类型检查
用途:
相关类型的转换,如整型到枚举,浮点到整型
显式转换,即使造成精度丢失,编译器也不会警告
与
void*
的双向转换
reinterpret_cast
编译期内
不做任何检查的转换,保证再次转换回来时,值不变(前提是转换的类型有足够的空间存储原有值)
危险性最高,完全靠程序员掌握
不生成任何CPU指令,对编译器而言,直接把该值作为指定类型(变量的属性)操作
用途:
- 主要用于不相关类型间转换,如整型到指针,不同指针类型间
1 | int i = 1; |
const_cast
添加或移除const
,volatile
修饰
- 不生成任何CPU指令,对编译器而言,本身这个修饰只是一种存取权限控制
dynamic_cast
运行期内转换
提供类型安全检查,可以知道转换是否成功
最耗时
用途:
在同一个继承体系(带有虚函数表的)中进行类型转换
子类向基类的向上转型(Up Cast)
基类向子类的向下转型(Down Cast)
横向转型(Cross Cast)