必须显式加 virtual 并搭配 override:基类析构函数声明 virtual 后,派生类析构自动具虚性,但不写 virtual 会降低可读性、丧失编译期检查,易致资源泄漏。

不需要,但强烈建议显式加上 virtual。 这不是语法强制要求,而是可读性、可维护性和防错的关键实践。
为什么不加 virtual 也能构成重写?
因为析构函数的重写是编译器特殊处理的例外情况:基类析构函数一旦声明为 virtual,派生类中只要定义了析构函数(哪怕没写 virtual),它就自动继承虚属性,与基类析构函数构成重写。底层统一被编译为 destructor 符号,所以“函数名不同”不破坏重写规则。
这意味着下面两种写法在功能上等价:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
class Base { public: virtual ~Base() = default; };
class Derived : public Base { public: ~Derived() override { /* OK */ } }; // 没写 virtual,但仍是虚的
class Derived2 : public Base { public: virtual ~Derived2() override { /* 更推荐 */ } }; // 显式写 virtual
不写 virtual 容易踩的坑
- 阅读代码时无法一眼判断该析构函数是否参与多态销毁,尤其在大型继承链中容易误判生命周期行为
- 如果后续把基类析构函数的
virtual去掉(比如重构时误删),派生类析构函数仍能编译通过,但已失去虚性——此时delete base_ptr就会漏调派生类析构,引发资源泄漏 - 缺少
override修饰时,若函数签名意外变化(比如参数多了个const或返回类型微调),编译器不会报错,而是静默变成一个普通析构函数,重写失效
正确写法:virtual + override 是黄金组合
显式写 virtual 并搭配 override,既表明设计意图,又让编译器帮你守住契约:
立即学习“C++免费学习笔记(深入)”;
-
virtual告诉所有人:“这个析构函数必须参与多态销毁” -
override强制校验:它确实重写了某个基类虚析构函数;一旦基类析构函数被改名、去 virtual 或签名变动,立刻编译失败 - 即使基类析构是纯虚的(
virtual ~Base() = 0;),派生类也必须提供定义,并用virtual ~Derived() override声明
真正容易被忽略的是:析构函数的虚性不是靠“子类有没有写 virtual”决定的,而是由“基类有没有写”决定的;但子类不写,就等于主动放弃可读性与编译期防护——而这两点,在资源管理密集的 C++ 项目里,往往比少敲两个字母重要得多。

















