static_cast,reinterpret_cast,dynamic_cast, const_cast
本文测试并描述这四种cast,编译器对应产生的行为
- static_cast
编译器对static_cast类型的转换会做静态类型检查,允许标准类型的互转,允许其他类型到void的转换,不允许互相之间无关联的class之间的转换,会在编译阶段拦截,允许有关联(有继承关系)的class之间互相转换,会静态分析这两个class之间的关联并做静态地址变换,但不保证转换的安全性,如果把void类型指针通过static_cast转换为某个class,这种行为是允许的(不会静态拦截),但由于静态分析时获取不到void类型指针所指对象的真实类型,不会做静态地址变换,因而可能转换出不符合预期的地址。
- dynamic_cast
编译器只对class做dynamic_cast转换,如果不是class而是其他类型,会在编译阶段拦截,如果此class不是多态的(至少包含一个虚函数),也会在编译阶段拦截,不允许互相之间无关联的class之间的转换,如果以上条件都满足,dynamic_cast也会静态分析这两个class之间的关联并做静态地址变换,同时通过运行时检查保证转换的安全性,如果是不安全的转换(比如指向父类对象的父类指针,dynamic_cast成指向子类的指针),那么dynamic_cast返回null
- reinterpret_cast
直接重新解释成目标类型,完全由调用者保证安全性。
为什么引入这些转换机制
C语言本身的类型转换够用吗?
只能做简单的标准类型转换
static cast
由于C++引入了类继承,类之间关系变得复杂,尤其在多重继承的场景下,类型转换可能要根据类型对指针做修改,需要引入static_cast
dynamic cast
在static_cast基础上增强了动态安全性检查
reinterpret_cast
和C语言本身的强制类型转换一样,只是通过统一名字方便查找