C++中的const_cast、static_cast、dynamic_cast和reinterpret_cast
C++类型转换
典型的C类型转换如下所示
1 | Typename_1 var_type_1; |
在C语言中,不管什么类型的转换都可以使用上述的形式;C++也支持上述类型的强制类型转换,但是这种转换可能会带来一些隐患,所以C++提供了四个在不同场合的强制类型转换函数:const_cast
, static_cast
, dynamic_cast
, reinterpret_cast
一、const_cast
const_cast用于修改指针或者引用,将指针或引用的常量形式转为非常量的形式,并且仍然指向原来的对象
SUM:
- 修改指针或者引用
- 常量转为非常量
Code:
1 | # 正常的使用方法 |
二、static_cast
static_cast与C语言风格的强制转换效果一样
SUM:
常用于:
- 类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。注意:进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
- 基本数据类型之间的转换,如把int转换成char,把int转换成enum。安全性需要开发者来维护
注:
- 没有运行时检查,与C风格一样都存在安全隐患
- static_cast不能转换掉原有类型的const、volatile、或者 __unaligned属性。(前两种可以使用const_cast 来去除)
- c++ 的任何的隐式转换都是使用 static_cast 来实现
Code:
1 | class Base |
三、dynamic_cast
dynamic_cast
将基类指针(或引用)转换成继承类指针(或引用),dynamic_cast
会根据基类指针是否真正指向继承类指针做相应处理。
1 | class Base{ |
从上边的运行结果可以看出:
- 从子类到基类的指针dynamic_cast转换没有问题
- 从基类到子类的转换虽然编译没有报错,但是转换的sub_ptr是一个空指针,说明dynamic_cast在程序运行时对类型进行了检查(RTTI,运行期类型检查,Runtime type information)
这个检查主要来自虚函数,虚函数时dynamic_cast转换能够进行的前提条件。当一个类有一个虚函数,那么编译器会构造出来一个虚函数表来指示这些虚函数的地址,如果该类被继承并且子类实现了一个同名并具有相同的函数签名的方法重写了基类的方法,那么虚函数表中会将该函数指向新的地址。此时多态性体现:使用激烈的指针或引用指向子类的对象,调用该方法时会顺着虚函数表找到对应子类的方法。
四、reinterpret_cast
reinterpret_cast是强制类型转换符用来处理无关类型转换的,通常为操作数的位模式提供较底层的重新解释。
主要应用在:
- 任意指针之间的转换
- 引用之间的转换
- 指针和足够大的int类型之间的转换
- 整数到指针的转换
1 | int main() { |
参考
【1】C++虚函数表剖析
【2】dynamic_cast
原文链接: https://www.delta1037.cn/2020/C_C++/C++类型转换/
版权声明: 转载请注明出处.