Effective C++ 条款07:为多态基类声明virtual析构函数

Effective C++ 条款07:为多态基类声明virtual析构函数


核心思想当通过基类指针删除派生类对象时,如果基类没有虚析构函数,会导致派生类资源泄漏。因为此时只会调用基类的析构函数,而不会调用派生类的析构函数。

⚠️ 1. 问题场景:非虚析构函数导致资源泄漏
class Base {
public:Base() { std::cout << "Base构造\n"; }~Base() { std::cout << "Base析构\n"; } // 非虚析构函数
};class Derived : public Base {
public:Derived() : data(new int(42)) { std::cout << "Derived构造\n"; }~Derived() { delete data; // 释放资源std::cout << "Derived析构\n"; }
private:int* data; // 派生类独占资源
};int main() {Base* pb = new Derived(); // 基类指针指向派生类对象delete pb; // 仅调用Base::~Base() → 内存泄漏!
}

输出结果

Base构造
Derived构造
Base析构

问题Derived的资源data未被释放 → 内存泄漏!


2. 解决方案:声明虚析构函数
class Base {
public:Base() { std::cout << "Base构造\n"; }virtual ~Base() { std::cout << "Base析构\n"; } // 虚析构函数
};class Derived : public Base { /* 实现同上 */ };int main() {Base* pb = new Derived();delete pb; // 正确调用派生类析构函数
}

输出结果

Base构造
Derived构造
Derived析构  // 先调用派生类析构函数
Base析构    // 再调用基类析构函数

🔍 3. 关键原则
场景析构函数要求原因
多态基类(有虚函数)必须virtual确保通过基类指针删除派生类对象时,正确调用派生类析构函数
非多态基类(无虚函数)不应virtual避免虚表指针带来的空间开销(条款7指出每个对象增加4-8字节)
STL容器(如std::string禁止继承标准库类的析构函数均为非虚,通过基类指针删除派生类对象会导致未定义行为

⚠️ 4. 错误实践:继承STL容器类
class MyString : public std::string { 
public:~MyString() { std::cout << "MyString析构\n"; }
};int main() {std::string* ps = new MyString(); delete ps; // 未定义行为!std::~string非虚
}

结果MyString::~MyString()不会被调用 → 潜在资源泄漏!


💎 5. 纯虚析构函数的特殊用法

使类成为抽象类,同时仍需要提供实现

class AbstractBase {
public:virtual ~AbstractBase() = 0; // 纯虚声明
};
AbstractBase::~AbstractBase() {}  // 必须提供实现class Concrete : public AbstractBase {
public:~Concrete() override { std::cout << "Concrete析构\n"; }
};int main() {AbstractBase* p = new Concrete();delete p; // 正确调用链:Concrete::~ → AbstractBase::~ 
}

总结:多态基类虚析构三原则

  1. 多态基类必须声明虚析构函数
    virtual ~Base() = default;
  2. 非多态基类不要声明虚析构函数
    避免无谓的虚函数表开销
  3. 禁止继承无虚析构函数的类(如STL容器)
    组合优于继承:将目标类作为成员变量而非基类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93220.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++进阶—C++11

第一章&#xff1a;C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中的漏洞进行修复&#xff0c;语言的核心部分则没有改动&#xff0c;因此人们习惯性…

把振动数据转成音频并播放

把振动数据转声音并播放 1、实现流程 安装第三方库: pip install numpy==1.23.5 pip install scipy==1.10.1 pip install sounddevice==0.4.6流程: 1、导入振动数据 2、数据归一化到[-1, 1]范围 3、重采样到44.1kHz 4、播放音频 5、保存音频为WAV文件(可选)2、代码示例 …

ServBay 1.15.0 更新,拥抱 Bun Deno 新生态

历时一个月&#xff0c;ServBay迎来了1.15.0的更新。我们始终坚信&#xff0c;一个优秀的本地开发环境&#xff0c;不仅要稳定、高效&#xff0c;更要紧跟技术的演进脉搏。ServBay 的使命是为开发者扫清开发环境配置的障碍&#xff0c;让您能聚焦于创造本身。 本次ServBay 1.1…

Java设计模式-通俗举例

设计模式就像做菜的食谱&#xff0c;告诉我们遇到常见问题时该用什么"烹饪方法"。今天我就用最生活化的例子&#xff0c;带大家轻松掌握23种设计模式的精髓。一、创建型模式&#xff08;5种&#xff09;&#xff1a;怎么"造东西"1. 单例模式&#xff1a;公…

【跟我学YOLO】YOLO12(3)训练自己的数据集

欢迎关注『跟我学 YOLO』系列 【跟我学YOLO】&#xff08;1&#xff09;YOLO12&#xff1a;以注意力为中心的物体检测 【跟我学YOLO】&#xff08;2&#xff09;YOLO12 环境配置与基本应用 【跟我学YOLO】&#xff08;3&#xff09;YOLO12 训练自己的数据集 【跟我学YOLO】&…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情分析实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解微博舆情分析实现 视频在线地址&#xff1…

【C++】手搓一个STL风格的vector容器

TOC(手搓一个STL风格的vector容器) 手搓一个STL风格的vector容器 github地址 有梦想的电信狗 0. 前言&#xff1a;动态数组的工程实践 ​ 在C标准库中&#xff0c;vector容器作为最核心的序列式容器&#xff0c;其设计融合了动态数组的高效性与安全性。本文将通过完整实现…

24. 了解过 webp 吗

总结 一种图片格式 一、什么是 WebP&#xff1f; WebP&#xff08;发音为 “weppy”&#xff09;是由 Google 推出的一种现代图片格式&#xff0c;支持有损压缩和无损压缩&#xff0c;旨在提供更小的文件体积和更高质量的图像显示。 它兼容常见的图片功能&#xff0c;如&#…

【Unity笔记】Unity Camera.cullingMask 使用指南:Layer 精准控制、XR 多视图与性能提升

Unity Camera.cullingMask 使用指南&#xff1a;Layer 精准控制、XR 多视图与性能提升 关键词&#xff1a;Unity、Camera、Culling Mask、Layer 控制、XR 渲染分离、UI 显隐、性能优化 特别说明&#xff1a; 本文为近期项目所遇问题的总结&#xff0c;仅纯文字记录&#xff0c;…

携带参数的表单文件上传 axios, SpringBoot

页面上的表单如上图, 点击确定按钮需要把参数统一传给后端.前端代码:表单的提交方法const submit async () > {const formData new FormData();formData.append("bookName", bookForm.value.bookName);formData.append("author", bookForm.value.auth…

黑马JavaWeb【复习到哪更新到哪】

登录认证&#xff08;复习Javaweb的登录校验&#xff09; 登录功能 思路就是loginController->service层->mapper层&#xff0c;从数据库中查找username和password是否和前端用户提交的表单内容一致&#xff0c;一致就登录成功&#xff0c;否则就返回登录失败的信息。 登…

NVMe高速传输之摆脱XDMA设计21:PCIe请求模块设计(下)

在接收到请求总线接口的请求事务后&#xff0c;当请求类型的值为0时&#xff0c;表示通过PCIE硬核的配置管理接口发送请求&#xff0c;由于请求接口的接口和时序与配置管理接口基本一致&#xff0c;因此此时直接将请求接口信号驱动到配置管理接口完成请求的发送&#xff0c;请求…

机器学习sklearn:不纯度与决策树构建

不纯度与决策树构建不纯度概念&#xff1a;决策树通过不纯度指标来选择最佳分割节点和分枝方式不纯度衡量节点中样本类别的混杂程度不纯度越低&#xff0c;节点中样本类别越纯净&#xff0c;拟合效果越好常用不纯度指标&#xff1a;信息熵(Entropy)&#xff1a;基于信息论的概念…

rk356x IR红外发射与接收之NEC协议

红外接收红外接收头解码器&#xff08;红外信号解码&#xff0c;主要是NEC解码&#xff09;红外发射器红外发光二极管晶振NEC编码组成共32位&#xff08;4bit&#xff09;&#xff1a;由8位用户码1 8位用户码2 8位命令码 8位命令码反码有时会存在按键一直按下的一帧信息&…

C++算法之单调栈

C算法中的单调栈&#xff1a;从入门到实战指南 大家好&#xff01;今天我们来聊聊C算法中一个超级实用的工具——单调栈。别被名字吓到&#xff0c;它其实很简单&#xff0c;就像排队买奶茶一样&#xff1a;队伍总是从矮到高&#xff08;或从高到矮&#xff09;排得整整齐齐&a…

React入门指南——指北指南(第二节)

React 实践:创建你的第一个待办事项列表 在前面的章节中,我们学习了 React 的核心概念(组件、Props、State 等)。本节将通过一个实际案例——创建待办事项列表(Todo List),帮助你巩固这些概念,并掌握 React 中处理用户交互、动态数据的基本方法。 案例目标 我们将构…

WAIC看点:可交付AI登场,场景智能、专属知识将兑现下一代AI价值

7月28日&#xff0c;为期三天的2025世界人工智能大会&#xff08;WAIC 2025&#xff09;在上海落下帷幕。作为全球 AI 领域最受关注的盛会之一&#xff0c;今年 WAIC 聚焦 AI 关键命题&#xff0c;围绕大模型与智能体应用、算力新基建及大数据、智能终端与具身智能、AI金融、AI…

设计模式(十一)结构型:外观模式详解

设计模式&#xff08;十一&#xff09;结构型&#xff1a;外观模式详解外观模式&#xff08;Facade Pattern&#xff09;是 GoF 23 种设计模式中的结构型模式之一&#xff0c;其核心价值在于为一个复杂的子系统提供一个统一、简化的高层接口&#xff0c;从而降低客户端与子系统…

接口测试核心概念与实践指南

核心概念什么是接口&#xff1f;软件不同部分之间进行通信和数据交换的约定或契约。定义了&#xff1a;请求方 (Client/Consumer) 如何调用&#xff08;方法、URL、参数&#xff09;。提供方 (Server/Provider) 如何响应&#xff08;数据结构、状态码&#xff09;。双方需要遵循…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 热词数量分析日期统计功能实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解热词数量分析日期统计功能实现 视频在线地…