编程语言中必然有很多情况需要转换类型。比如引入const的概念就为了提高安全性,编译器提前检查,避免一些意外修改。当然,有时,我们希望手动转换一个变量的类型,让其变成常量,可以利用编译器提供的cast方法。
- C++早期提供了const_cast,写法繁琐,C++17引入std::as_const写法更轻松,C++20引入bit_cast可实现位级别复制,而非普通float和int转换后丢失小数位的问题。
隐式转换和强制转换
编译器为了简化不同类型变量互操作,引入隐式转换,可以安全转换(不损失数据)数据,此过程由编译器自动完成。当不满足如上条件,需要程序员手动用强制类型转换。
- C/ObjC/C++ 语言大小小于int的整型(包括char和枚举)的类型使用时都自动转换成int. 有人有疑问,这样不是占用空间变大吗?事实上,仅仅是使用时,数据保存依然按对应类型。为什么使用时要转换成int呢?因为CPU操作int最自然,换成char或short一样会使用int大小的寄存器,没好处。下图push eax保存字符c,并传递给printf做参数。

- Swift 是一门相对安全的语言,没有隐式类型转换。
父类子类转换
子类本身就是父类的一种,转换成父类很自然,但父类转换成子类就需要考虑对不对。
- C++提供dynamic_cast主要为了继承体系转换,比static_cast更智能。虽然C++支持强制转换,必要时也可以通过typeid判断类型是否一致。
- Java默认也不允许父到子转换,但如果确定父对象引用确实是子对象,可用强制类型转换。
- C#不提供基类强转成派生类的方法。
- Python提供了简单的转换方式type(<Derived Class>)(<Base Class>).
- JS ES6虽然引入了类,一般无必要做父类子类转换。
- Go/Rust并不是纯粹的OOP语言,需要做一些手脚。
枚举
- C/C++常规枚举可以和整形做隐式转换,C++11引入作用域为类的枚举,不允许此行为以加强安全性,但可以使用显式转换。
浮点数和整数的转换
- C/ObjC/C++/仓颉
浮点数转换成整数,会丢弃小数。
