dynamic_cast失败时指针返回nullptr、引用抛std::bad_cast异常;需基类多态且RTTI启用,智能指针应使用dynamic_pointer_cast。

dynamic_cast 转换失败时返回 nullptr(指针场景)
当用 dynamic_cast 将基类指针转为派生类指针,而实际对象并非目标类型时,它会返回 nullptr,不会崩溃或未定义行为。这是最常见、最安全的使用方式。
- 必须确保源类型是多态的(含至少一个虚函数),否则编译直接报错:
error: cannot dynamic_cast '...' (source type is not polymorphic) - 转换后务必判空,不能直接解引用:
if (d) { d->derivedMethod(); },否则可能触发空指针访问 - 返回的是目标类型的空指针,类型严格匹配,比如
dynamic_cast<derived>(ptr)</derived>失败 → 返回Derived*类型的nullptr,不是void*或其他
dynamic_cast 转换失败时抛 std::bad_cast(引用场景)
对引用使用 dynamic_cast 时,失败不会返回空值——C++ 标准规定它必须抛出 std::bad_cast 异常。这容易被忽略,且一旦没捕获就会导致程序终止。
- 示例:
Derived& d = dynamic_cast<derived>(base_ref);</derived>—— 若base_ref实际绑定的是Base对象,立即抛异常 - 必须用
try/catch包裹,且捕获类型要精确:catch (const std::bad_cast&) - 引用转换无法“静默失败”,不适合做类型探测逻辑;想试探类型请优先用指针形式
std::shared_ptr 的 dynamic_pointer_cast 失败返回空智能指针
对智能指针做运行时向下转型,应使用 dynamic_pointer_cast,而不是对裸指针 cast 后再构造 shared_ptr。它失败时返回空 std::shared_ptr,语义清晰、安全。
- 返回值可直接用于布尔判断:
if (auto d_ptr = dynamic_pointer_cast<derived>(base_ptr)) { ... }</derived> - 注意:它依赖底层对象的 RTTI,所以
base_ptr指向的对象仍需是多态类型 - 不要混用:
static_pointer_cast不做运行时检查,误用会导致后续访问派生类成员时崩溃
RTTI 被禁用时 dynamic_cast 会怎样
某些构建配置(如 GCC 的 -fno-rtti)会彻底关闭 RTTI 支持,此时所有 dynamic_cast 用法在编译期就报错,连基本语法都不通过。
立即学习“C++免费学习笔记(深入)”;
- 错误信息典型为:
error: 'dynamic_cast' not permitted with -fno-rtti - 这时若需要类似能力,只能靠手动类型标记(如枚举字段)+
static_cast,但失去安全性保障 - 跨模块或第三方库若依赖 RTTI,禁用后可能出现链接失败或运行时
typeid行为异常,影响不止dynamic_cast
dynamic_cast 没加 try/catch,以及忘了基类必须有虚函数——哪怕只写个 virtual ~Base() = default; 也行,但缺了它,编译器连让你试错的机会都不给。


















