You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何dynamic_cast要求基类拥有virtual析构函数?

关于dynamic_cast报错与多态类类型的疑问

代码示例

struct Base {
    Base() {}
    ~Base() {}
};
 
struct Derived: public Base {
    Derived() {}
    ~Derived() {}
};
  
struct AnotherClass: public Base {
    AnotherClass() {}
    ~AnotherClass() {}
};
  
int main() {
    Derived* d = new Derived();
    Base* base = d;
 
    AnotherClass* ac = dynamic_cast<AnotherClass*> (base);
}

运行错误

the operand of a runtime dynamic_cast must have a polymorphic class type.

将Base类的析构函数设为virtual后问题得以解决,但有两个疑问:

  1. 为何此处需要基类拥有virtual析构函数,base才会被视为polymorphic class type?
  2. 既然Derived和AnotherClass继承自Base,它们难道不已经是polymorphic class type吗?

问题解答

首先明确C++里多态类类型(polymorphic class type)的定义:一个类只要包含至少一个虚函数(包括虚析构函数),它就是多态类。

回到你的代码:

  • 原始的Base类没有任何虚函数,所以它不是多态类。哪怕Derived和AnotherClass继承自它,这两个子类本身也没有自己的虚函数,所以它们同样不是多态类。
  • dynamic_cast做运行时类型转换的前提是:操作数的静态类型必须是多态类。因为运行时类型识别(RTTI)依赖虚函数表(vtable)来实现——每个多态类都会生成虚函数表,里面存储了类的类型信息,dynamic_cast就是通过这个表来判断实际类型是否匹配的。

为什么把Base的析构函数设为virtual就解决了?
因为一旦Base有了虚析构函数,它就变成了多态类。同时,子类会继承这个虚析构函数(哪怕子类自己没显式声明),所以Derived和AnotherClass也自动成为多态类了。这时候base指针的静态类型是Base(多态类),满足dynamic_cast的运行时转换要求,就能正常执行类型检查了。

补充一点:其实不一定非要用虚析构函数,给Base加任意一个虚成员函数(比如虚的void foo())也能解决这个问题。不过给基类加虚析构函数是更规范的做法——避免通过基类指针删除子类对象时出现内存泄漏。

内容的提问来源于stack exchange,提问作者Shishir Jessu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:22:20