

新闻资讯
技术学院基类析构函数不加 virtual 会导致资源泄漏,因为用基类指针 delete 派生类对象时仅调用基类析构,跳过派生类析构逻辑,使堆内存、文件句柄等无法释放;只要存在多态删除可能(如基类被继承或用于智能指针),就必须声明为 virtual,否则引发隐蔽泄漏。
virtual 会导致资源泄漏当用基类指针指向派生类对象,并通过该指针 delete 时,若基类析构函数不是虚函数,C++ 只会调用基类的析构函数,**完全跳过派生类的析构逻辑**。这意味着派生类中申请的堆内存、打开的文件句柄、持有的锁等资源无法被释放。
典型错误现象:
Base* p = new Derived(); delete p; // 只调用 ~Base(),~Derived() 被静默忽略
new 出来的内存不会被 delete
std::ofstream 或 FILE* 不会关闭,可能丢失数据virtual
只要存在「多态删除」的可能,就必须加 virtual。核心判断依据不是“有没有继承”,而是“会不会用基类指针/引用来管理派生类对象的生命周期”。
virtual
virtual 函数(除析构外)→ 析构也应为 virtual,否则行为不一致std::vector<:unique_ptr>>)→ 必须加 virtual
virtual 有什么代价?虚析构函数会让类变成多态类型,从而引入虚函数表指针(vptr),每个对象增加一个指针大小的开销(通常 8 字节)。但这只是**对象实例的内存开销**,不影响性能热点。
delete 时发生一次,且现代编译器常能内联virtual(符合预期)反例:有人为省 8 字节而省略 virtual,结果导致难以追踪的资源泄漏—
—这远比内存开销严重得多。
标准写法是声明为 virtual,且推荐显式加上 = default 或空实现,避免意外生成非虚版本。
class Base {
public:
virtual ~Base() = default; // ✅ 推荐:简洁、明确、无副作用
// 或
// virtual ~Base() {} // ✅ 也可,但不如 = default 清晰
};virtual ~Derived(),基类没写 → 多态删除仍只调用基类析构virtual void cleanup() 而非析构函数 → 无法自动触发,必须手动调用virtual ~Base() = default,为子类留出安全出口最易被忽略的一点:即使你当前所有派生类都只用栈对象(Derived d;),只要未来有人把它放进 std::unique_ptr 或传给某个通用销毁函数,没加 virtual 的基类析构就会立刻变成隐患。