基类指针存了多个子类的对象,取出来想调子类特有的方法,直接调调不出来,硬转又怕类型错了崩溃。这时候就得靠带运行时检查的类型转换,它会在运行时核对你的猜测,结果安全可验证。

它和普通转换的区别

普通转换只管把比特位重新解释,不问你转得对不对,错了就是未定义行为,埋雷等炸。带检查的转换会查运行时类型信息,成功返回可用结果,失败给明确信号。指针失败返回空指针,引用失败抛类型错误异常,两种信号对应两种检查习惯。

指针转换的检查模式

存的真是目标类型,转换成功拿到可用指针,直接调子类方法。猜错了返回空,用前判空就能安全处理,不用提前知道具体是哪个子类。注意它只对带虚函数的类有效,没有虚函数的类没有运行时信息可用,会直接编译报错。涉及多继承的交叉转换,它能顺着继承网自动算偏移,手工算偏移容易错位。

引用转换的异常模式

引用没有空这个状态,失败时用抛异常的方式通知,调用处把可能抛异常的调用包起来,捕获对应类型即可。适合确信应该成功、失败就是逻辑错误的场景。频繁用要留意开销,循环热点里反复检查会拖慢速度,能提前一次判断的就不要每轮都转。

什么时候该用、什么时候换招

插件系统、多态消息、序列化后的对象重建,用它做类型分流很顺手。但条件分支里一长串地转,说明设计有问题,该给基类加虚方法把行为下放。枚举加分支能表达的就别用它,多一层类型信息就多一分开销。顶层条件里处理完,其他地方就用虚方法,别到处散落转换逻辑。

  • 检查口诀:指针判空、引用捕获,两套信号别混
  • 前置条件:基类必须带虚函数,否则没有运行时信息可用
  • 设计提醒:满屏类型转换是坏味道,优先用虚方法下放行为
子类指针等于带检查转换(目标指针)(基类指针)若结果为空则猜错类型引用转换失败抛类型错误异常带虚函数的基类才有运行时信息一处转换多处虚方法替代满屏转换