不能,编译直接报错;dynamic_cast要求基类至少有一个虚函数(如虚析构函数)以支持rtti,否则因无虚表而无法运行时类型检查。

不能,编译直接报错。 dynamic_cast 要求基类必须是多态类型,也就是至少有一个虚函数(通常是虚析构函数),否则连编译都过不去。
为什么编译器会拒绝:error: "operand of dynamic_cast must be a pointer to a polymorphic type"
这个错误信息很直白:dynamic_cast 的操作数必须是指向多态类型的指针。所谓“多态类型”,就是定义了虚函数的类——只有这时,对象才带虚表指针(vptr),运行时才能通过虚表找到 RTTI(Run-Time Type Information)数据。
没有虚函数 → 没有虚表 → 没有 RTTI → dynamic_cast 失去检查依据,编译器干脆禁止你用。
- 即使派生类自己有虚函数,只要基类没虚函数,
dynamic_cast依然失败 - 基类中加一个
virtual ~Base() = default;就够了,不一定要有其他虚函数 - 仅靠
virtual关键字声明(哪怕函数体为空)就足以触发 RTTI 生成
static_cast 能绕过这个限制吗?
能,但非常危险。
static_cast 不依赖 RTTI,它只做编译期的类型关系推导,所以基类有没有虚函数完全不影响它编译通过。
-
static_cast<derived>(base_ptr)</derived>在语法上永远合法(只要继承关系存在) - 但如果
base_ptr实际指向的是Base对象(而非Derived),后续访问Derived特有成员就会读错内存,行为未定义 - 多重继承下,
static_cast还可能因偏移计算错误导致指针值偏差,而你完全察觉不到
常见误判场景:以为“向上转型成功”就代表能向下转回来
很多人写完 Base* b = new Derived;,看到多态调用正常,就以为 dynamic_cast<derived>(b)</derived> 肯定能行——但忘了检查基类是否有虚函数。
- 如果
Base没虚函数,这行代码根本编译不过,和对象实际类型无关 - 如果项目禁用了 RTTI(比如编译时加了
-fno-rtti),即使基类有虚函数,dynamic_cast也会失效或退化为static_cast行为 - 私有/保护继承、非虚的钻石继承,也会让
dynamic_cast编译失败或结果不可靠
最容易被忽略的一点:RTTI 不是“有虚函数就自动全开”,它依赖编译器选项、继承方式、以及整个继承链的可见性。哪怕只漏掉一个 virtual 或配错继承权限,dynamic_cast 就可能突然哑火。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











