当前位置: 首页 > web >正文

C++中析构函数不设为virtual导致内存泄漏示例

一、问题示例

#include <iostream>
using namespace std;class Base {
public:Base() { cout << "Base constructor\n"; }~Base() { cout << "Base destructor\n"; } // 不是 virtual
};class Derived : public Base {
public:Derived() { cout << "Derived constructor\n"; }~Derived() { cout << "Derived destructor\n"; }
};int main() {Base* ptr = new Derived();  // 用 Base 指针指向 Derived 对象delete ptr;                 // 只调用 Base 的析构函数return 0;
}

二、输出结果

在这里插入图片描述
注意:没有调用 Derived 的析构函数

三、问题解释

为什么会这样?

  • Base 的析构函数不是 virtual

  • 当你执行 delete ptr,编译器只看 ptr 的静态类型(即 Base*),它就只调用 ~Base()

  • 因此,不会调用 Derived 的析构函数,可能会导致:

    • Derived 析构中释放的资源没有释放(内存泄漏);
    • 或者 Derived 析构中有清理逻辑没执行(行为错误);

四、修复方法

Base 的析构函数设为 virtual

class Base {
public:virtual ~Base() { cout << "Base destructor\n"; }  // virtual 析构
};

正确输出:

在这里插入图片描述


五、图示原理(简化)

如果你用 virtual

Base vtable:
+----------------+
|  &Base::~Base  |  ← 原始虚函数地址
+----------------+Derived vtable:
+--------------------+
| &Derived::~Derived | ← 覆盖虚析构函数
+--------------------+delete ptr 会通过 vtable 跳转到 Derived::~Derived → 再调用 Base::~Base

六、总结

是否 virtualdelete 派生类指针时行为是否内存泄漏
只调用基类析构函数有可能
调用派生 → 再基类析构安全

七、经验建议

只要类中有虚函数(即打算支持多态)或你“可能”通过基类指针删除派生类对象,就应该将析构函数声明为 virtual

最好这样写:

class Base {
public:virtual ~Base() = default;
};
http://www.xdnf.cn/news/7012.html

相关文章:

  • 电子电路:电位器和可变电阻是同一个东西吗?
  • 2025年【道路运输企业安全生产管理人员】考试题库及道路运输企业安全生产管理人员考试内容
  • 获取淘宝店铺所有商品信息接口数据指南
  • JavaScript splice() 方法
  • 【C++】string的使用【上】
  • Linux面试题集合(6)
  • PIC16F18877 ADC 代码
  • Python绘制南丁格尔玫瑰图:从入门到实战
  • 专题四:综合练习(组合总和的暴搜dfs)
  • printf耗时高的原因
  • UE 材质基础 第一天
  • nginx集成防火墙ngx_waf的docker版
  • 重庆 ICPC 比赛游记
  • Vue 3.0中响应式依赖和更新
  • list重点接口及模拟实现
  • 从复杂系统(杂多集合的实例)到智慧系统(理想集合的建构)
  • docker迅雷自定义端口号、登录用户名密码
  • 【嵌入式项目-MCU代码2】
  • Bitmap、Roaring Bitmap、HyperLogLog对比介绍
  • BootCDN介绍(Bootstrap主导的前端开源项目免费CDN加速服务)
  • LLM笔记(二)LLM数据基础-分词算法(2)
  • Linux面试题集合(1)
  • 前端扫盲HTML
  • 深入理解构造函数,析构函数
  • 威布尔比例风险模型(Weibull Proportional Hazards Model, WPHM)详解:原理、应用与实施
  • MATLAB进行深度学习网络训练
  • WSL 安装 Debian 12 后,如何安装图形界面 X11 ?
  • 【论文#目标检测】End-to-End Object Detection with Transformers
  • 在Maven中使用Ant插件
  • 【和春笋一起学C++】(十四)指针与const