dynamic_cast只能用于多态类型,因为它依赖RTTI,而RTTI仅在含虚函数的类中生成;无虚函数则编译失败或抛std::bad_cast。

dynamic_cast 为什么只能用于多态类型
因为 dynamic_cast 依赖运行时类型信息(RTTI),而 RTTI 只在至少有一个虚函数的类中生成。没有虚函数的类,编译器不为其生成 vtable 和类型描述符,dynamic_cast 就会编译失败(指针转换)或抛出 std::bad_cast(引用转换)。
常见错误现象:error: cannot dynamic_cast ... (source type is not polymorphic)
- 确保源类和目标类都继承自有虚函数的基类(哪怕只有
virtual ~Base() = default;) - 不能对
void*、内置类型、普通结构体(无虚函数)做dynamic_cast - 向下转型(派生 → 基类)其实不需要
dynamic_cast,用隐式转换或static_cast更合适
指针转换失败时返回 nullptr,引用转换失败直接抛异常
这是最易踩的坑:用 dynamic_cast 转引用却没包 try/catch,程序崩溃;转指针却忘了判空,导致段错误。
示例:
立即学习“C++免费学习笔记(深入)”;
Base* b = new Derived2(); Derived1* d1 = dynamic_cast(b); // 返回 nullptr if (d1) { /* 安全使用 */ } Derived1& r1 = dynamic_cast
(b); // 抛 std::bad_cast!
- 优先用指针形式,便于显式判空
- 非得用引用时,必须捕获
std::bad_cast - 别把
dynamic_cast当“万能安全转换”——它只解决“是不是这个确切类型”的问题,不是类型适配器
和 static_cast、reinterpret_cast 的关键区别在哪
dynamic_cast 唯一不可替代的场景是:在继承体系中,确认一个基类指针/引用**实际指向的是哪个具体派生类型**,且该判断必须发生在运行时。
-
static_cast:编译期检查,允许上行(派生→基类)、下行(基类→派生)甚至无关类型转换(如int→void*),但不验证实际对象类型,错用必 UB -
reinterpret_cast:完全绕过类型系统,仅重解释比特位,危险且与dynamic_cast零交集 -
dynamic_cast:仅限类层次间指针/引用转换,且只在 RTTI 启用、类型确实匹配时成功;其他情况明确失败(nullptr或异常)
性能影响:每次调用都有 vtable 查找 + 类型比较开销,高频循环里慎用。
RTTI 被禁用时 dynamic_cast 会怎样
某些嵌入式或性能敏感项目会通过编译选项(如 GCC/Clang 的 -fno-rtti)关闭 RTTI。此时 dynamic_cast 无法链接,报错类似:undefined reference to `typeinfo for ...'。
- 启用 RTTI 是使用
dynamic_cast的硬性前提,不是可选优化 - 关闭 RTTI 后,连
typeid也失效,所有依赖运行时类型识别的逻辑都要重构 - 若必须禁用 RTTI 又需类型判断,得手动实现(如加枚举字段 +
switch),但失去自动维护性和安全性
真正麻烦的不是语法怎么写,而是忘记 RTTI 是个开关——它关了,dynamic_cast 就彻底不存在,连编译都过不去。








