安全的向下类型转换必须使用 dynamic_cast,且要求类为多态类型(含虚函数);对指针失败返回 nullptr,对引用失败抛 std::bad_cast 异常;需检查空指针或捕获异常,禁止使用 static_cast 或 C 风格转换。

在 C++ 中,安全的向下类型转换必须依赖 dynamic_cast,且仅适用于**多态类型**(即含有至少一个虚函数的类)。它会在运行时检查转换是否合法,失败时返回空指针(对指针)或抛出 std::bad_cast 异常(对引用),从而避免未定义行为。
前提:类必须是多态的
dynamic_cast 要求源类型(基类)至少有一个虚函数(通常是虚析构函数),否则编译失败。
- 基类中未声明虚函数 → dynamic_cast 编译报错
- 推荐为多态基类声明虚析构函数:
virtual ~Base() = default; - 即使没有其他虚函数,也应加虚析构,防止通过基类指针 delete 派生对象时析构不完整
对指针使用 dynamic_cast:检查空指针
转换指针时,失败返回 nullptr,需显式判断:
Derived* d = dynamic_cast(base_ptr); - 若
d != nullptr,说明base_ptr实际指向Derived或其派生类对象 - 切勿跳过空检查直接解引用,否则可能崩溃
对引用使用 dynamic_cast:捕获异常
引用无法为空,所以失败时抛出 std::bad_cast:
立即学习“C++免费学习笔记(深入)”;
try { Derived& d = dynamic_cast(*base_ref); /* 安全使用 d */ } catch (const std::bad_cast& e) { /* 处理转换失败 */ }- 适合逻辑上“必须是某类型”的场景,失败属于异常情况
不安全替代方案要避免
static_cast 和 C 风格转换((Derived*)ptr)在向下转换时不做运行时检查,若实际类型不符,结果是未定义行为 —— 可能读写错误内存、崩溃或静默错误。
- 仅当已通过其他手段(如类型标记)100% 确认类型时,才可考虑 static_cast,但通常不如 dynamic_cast 清晰可靠
- dynamic_cast 的开销很小(一次虚表查表 + 类型信息比对),现代编译器优化良好,不应因性能顾虑放弃安全性










