基类必须声明虚析构函数,否则通过基类指针delete派生类对象时仅调用基类析构函数,导致派生类资源未释放而泄漏;应声明为virtual ~Base() = default;,即使无资源清理也必须如此。
当用 new 创建派生类对象,再通过基类指针删除时,若基类析构函数不是 virtual,只会调用基类析构函数,派生类中新增的资源(如堆内存、文件句柄)不会被释放,造成内存泄漏或资源未关闭。这是多态销毁中最隐蔽也最危险的问题。
delete ptr; 后派生类的析构逻辑完全没执行delete 操作virtual 的基类析构函数,编译器按静态类型调用,不走虚表虚析构函数只需在基类中声明为 virtual,通常定义为空实现(除非需要清理基类资源),派生类析构函数自动成为虚函数,无需显式加 virtual 或 override(但加 override 更安全)。
class Base {
public:
virtual ~Base() = default; // 推荐:= default;或 {} 也可
};
class Derived : public Base {
public:
~Derived() override { / 清理 Derived 特有资源 / }
};
= default 是最简洁安全的选择,生成编译器默认行为virtual ~Base() = 0;),否则必须提供定义virtual,否则多态删除失效添加 virtual 会让类对象隐含一个虚表指针(vptr),增大对象体积(通常 8 字节),并引入一次间接跳转开销。但这仅发生在有虚函数的类上——虚析构本身不会额外增加开销,它只是“占个虚函数槽位”。
virtual void foo()),加虚析构几乎零成本
构,则对象大小+8字节,构造/析构略慢(可忽略)容易忽略的是:抽象基类、接口类、甚至只有纯虚函数的类,也必须有虚析构函数。Clang/GCC 的 -Wnon-virtual-dtor 警告能帮你在编译期发现这类问题。
class Interface { public: ~Interface(); }; —— 缺 virtual
class Interface { public: virtual ~Interface() = default; };
-Wall -Wnon-virtual-dtor(GCC/Clang)虚析构函数不是“可选的最佳实践”,而是多态对象生命周期管理的强制契约。漏掉它,程序可能长期运行无异常,直到某次派生类新增了 new 出来的成员,才突然崩溃或缓慢泄漏。
# 字节
# c++
# 为什么
# 多态
# 析构函数
# void
# 指针
# 虚函数
# 纯虚函数
# 接口
# 堆
# class
# public
# Interface
# delete
# 对象
# default
# 派生类
# 类中
# 的是
# 这是
# 句柄
# 只需
# 帮你
# 也可
# 只会
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
c++ std::future和std::promise c++线程间通信【教程】
Python迭代器生成器进阶教程_节省内存与懒加载实战
Win11系统更新后黑屏怎么办 Win11更新黑屏修复教程【方法】
php转mp4怎么保留字幕_php处理带字幕视频转换说明【说明】
c++怎么设置线程优先级与cpu亲和性_c++ 多核处理器性能绑定【指南】
C++如何将C风格字符串(char*)转换为std::string?(代码示例)
如何在Golang中使用log包输出不同级别日志_Golang log日志管理与分类
Win11开始菜单打不开_修复Windows 11点击开始图标无响应【教程】
使用类变量定义字符串常量时的类型安全最佳实践
MAC怎么解压RAR格式文件_MAC第三方解压工具安装与压缩包管理【教程】
Win11怎样彻底卸载自带应用_Win11彻底卸载自带应用方法【步骤】
Win11文件扩展名怎么显示 Win11查看文件后缀名设置【步骤】
Win11怎么关闭系统声音_Win11系统提示音静音设置【详解】
Win10如何卸载微软拼音输入法 Win10只保留一个输入法【教程】
如何在Golang中处理云原生事件_使用Event和Notification机制
微信短链接怎么还原php_用浏览器开发者工具抓包获取【方法】
如何高效获取循环末次生成的 NumPy 数组最后一个元素(无需额外循环)
c# 如何用c#实现一个支持优先级的任务队列
Windows怎样关闭锁屏广告_Windows关闭锁屏广告方法【教程】
Win10怎么限制单程序CPU占用上限_Win10任务管理器亲和性或第三方工具均衡负载【技巧】
Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
PHP主流架构如何做单元测试_工具与流程【详解】
Win10如何备份注册表_Win10注册表备份步骤【攻略】
Win11怎么设置屏保时间_调整Win11屏幕保护等待时间【详解】
Windows10系统怎么查看防火墙状态_Win10安全中心网络保护
Windows服务持续崩溃怎样修复_系统服务保护机制解析
Python数据挖掘进阶教程_分类回归与聚类案例解析
Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件
Python字符串操作教程_切片拼接与格式化详解
Windows10怎么查看硬件信息_Windows10硬件信息查询方法【指南】
如何在Golang中编写异步函数测试_Golang异步操作测试策略
如何在同包不同文件中正确引用 Go 结构体
phpstudy本地环境mysql忘记密码_重置mysqlroot密码操作流程【解答】
Python与OpenAI接口集成实战_生成式AI应用场景解析
c# 在高并发下使用反射发射(Reflection.Emit)的性能
Win10怎样清理C盘浏览器缓存_Win10清理浏览器缓存步骤【步骤】
C++如何使用std::optional?(处理可选值)
c++如何获取map中所有的键_C++遍历键值对提取所有key的方法
如何测试您的网站全球打开速度-网站海外测速工
Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】
Win10怎样清理C盘Steam游戏缓存_Win10清理Steam游戏缓存步骤【步骤】
php下载安装包怎么选_threadsafe与nts版本差异【解答】
如何使用Golang开发简单的聊天室消息存储_Golang WebSocket数据持久化方法
Win11怎么设置鼠标宏_Win11鼠标按键自定义编程教程【详解】
Mac如何开启夜览模式_Mac护眼模式设置与定时
Windows10系统怎么查看CPU温度_Win10性能监视器查看硬件数据
如何在 Go 中高效缓存与分发网络视频流
Linux如何安装JDK11_Linux环境变量配置与Java开发环境搭建【教程】
php转exe用什么工具打包快_高效打包软件推荐【汇总】
如何使用Golang实现容器自动化运维_Golang Docker运维管理方法
2026-01-01
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。