为多态基类声明virtual析构函数
我们知道,有时会让一个基类指针指向用 new 运算符动态生成的派生类对象(类似接口的作用);同时,用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类对象,而释放该对象时是通过释放该基类指针来完成的,就可能导致程序不正确。
比如,我们有一个钟表的基类 TimeKeeper用来计时,而我们又有原子钟、水钟、腕表等一系列子类,根据工厂模式,我们可以定义一个 getAtomicClock函数来获得一个原子钟指针,然后用基类指针TimeKeeper来指向它们,其他子类也是同理,这个TimeKeeper就相当于一个接口
#include <iostream>
using namespace std;class TimeKeeper
{
public:TimeKeeper() {};~TimeKeeper() { cout << "TimeKeeper::destrutor" << endl; }
};// 原子钟
class AtomicClock : public TimeKeeper
{~AtomicClock(){ cout << "AtomicClock::destrutor" << endl; }
};
class WaterClock : public TimeKeeper {}; // 水钟
class WristClock : public TimeKeeper {}; // 腕表TimeKeeper* getAtomicClock()
{return new AtomicClock;
}TimeKeeper* getWaterClock()
{return new WaterClock;
}TimeKeeper* getWristClock()
{return new WristClock;
}int main() {TimeKeeper* ptk = getAtomicClock();delete ptk;ptk = getWaterClock();ptk = getWristClock();
}如上面代码所示,我们的三个工厂函数都是用的基类来指向的,因为我们用的 new 来创建对象,所以自然要用 delete 释放掉,可是问题来了,我们的ptk指针是用基类指向子类对象,那么我们释放的时候是调用基类的析构还是子类的析构函数呢?答案是调用基类的析构!因为这里是静态联编,在运行之前,编译器只知道ptk是 TimeKeeper类型的,自然是调用基类的析构,但是我们实例化的是一个子类啊,你调用基类的析构,那子类中万一有一些基类没有的元素呢?那岂不是没有被析构造成内存泄漏了?

因此,为了解决这个问题,就轮到了virtual析构函数的出场了,我们只需要将基类的析构函数声明为虚析构即可!
virtual ~TimeKeeper() { cout << "TimeKeeper::destrutor" << endl; }
发现基类和子类的析构函数都被调用了!所以我们记住:问题的关键在于在实现多态的时候,堆区的内存可能会泄露,这是要用虚析构!
如果是引用的话,哪怕是多态不在堆区就不需要虚析构了:
AtomicClock ac;
TimeKeeper& ptk = ac;程序结束的时候,依然会调用基类和子类的析构函数:

最后让我们再记一条原则:类的设计目的如果不是作为基类使用,或者不是为了具备多态性,就不该声明虚析构函数!
相关文章:
为多态基类声明virtual析构函数
我们知道,有时会让一个基类指针指向用 new 运算符动态生成的派生类对象(类似接口的作用);同时,用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类…...
啊哈 算法读书笔记 第 2 章 栈、队列、链表
第 2 章 栈、队列、链表 目录 第 2 章 栈、队列、链表 队列: 解密回文——栈 纸牌游戏: 链表 模拟链表 队列: 首先将第 1 个数删除,紧接着将第 2 个数放到这串数的末尾,再将第 3 个数删除并将第 4 个数放到这串…...
Git ---- IDEA 集成 Git
Git ---- IDEA 集成 Git1. 配置 Git 忽略文件2. 定位 Git 程序3. 初始化本地库4. 添加到暂存区5. 提交到本地库6. 切换版本7. 创建分支8. 切换分支9. 合并分支10. 解决冲突1. 配置 Git 忽略文件 1. Eclipse 特定文件 2. IDEA 特定文件 3. Maven 工程的 target 目录 问题1…...
【LeetCode 704】【Go】二分查找
二分查找题解 一、碎碎念 从本周开始,重新更新刷题记录了哈。 基于费曼学习法的原理,最好的输入是输出,所以与大家分享。 鉴于目前这个糟糕的市场环境,还是要练好自己的基本技术,万一那天就被迫 N 1了,你…...
【代码随想录训练营】【Day23】第六章|二叉树|669. 修剪二叉搜索树 |108.将有序数组转换为二叉搜索树|538.把二叉搜索树转换为累加树
修剪二叉搜索树 题目详细:LeetCode.669 做这道题之前建议先看视频讲解,没有想象中那么复杂:代码随想录—修剪二叉搜索树 由题可知,需要删除节点值不在区间内的节点,所以可以得到三种情况: 情况一&#…...
CV——day78 读论文:通过静态背景构建扩展低通道路边雷达的探测距离(目标是规避风险)
Extending the Detection Range for Low-Channel Roadside LiDAR by Static Background Construction 通过静态背景构建扩展低通道路边雷达的探测距离I. INTRODUCTIONII. RELATED WORKA. LiDAR-Based 3-D Vehicle and Road User DetectionB. LiDAR Data Background FilteringC.…...
【编程入门】应用市场(go语言版)
背景 前面已输出多个系列: 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 《N种编程语言做个记事本》 目标 为编程初学者打造入门学习项目,使…...
Linux(openEuler)没有界面连接互联网方法
前言: 系统版本openEuleropenEuler-22.03-LTS-x86_64-dvd 我们在安装linux之后,一般都是无界面的情况。大部分情况都是需要自己安装界面的,如果路由器的情况下直接插上网络就好了。下面就开始介绍两种方法进行linxu网络的连接。 注意: 小编是使用的第一…...
第一天 软考中级--嵌入式系统设计师考试复习教程开始了
第一天 嵌入式系统设计师考试复习教程 第二天 软考中级--嵌入式系统设计师考试考试大纲解析 目录...
分享 10 个高频 Python 面试题
Python 很容易学会,但很难掌握。你可以在几天内了解它的基本语法,但是要能够用 Python 开发出足够好的商业软件,多年的实践是必须的。因为,无论你使用哪种编程语言,你都必须对其复杂的内部机制有足够的了解,…...
ThreadLocal原理、结构、源码解析
文章目录一、Thread简介1.什么是ThreadLocal2.为什么要是用ThreadLocal2.1Synchronized、Lock保证线程安全2.2ThreadLocal保证线程安全3.ThreadLocal和Synchronized的区别二、ThreadLocal原理1.Thread抽象内部结构2.ThreadLocal源码2.1Thread、ThreadLocal、ThreadLocalMap、En…...
分布式之PBFT算法
写在前面 在分布式之拜占庭问题 一文中我们分析了拜占庭问题,并一起看了支持拜占庭容错的口信消息性和签名消息性算法,但是这两种算法都有一个非常严重的问题,就是消息数量太多,通信的成本太大,消息数量复杂度为O(n ^…...
Linux 操作系统——查看/修改系统时区、时间、本地时间修改为UTC
文章目录1.背景描述2.知识储备3.解决步骤1. 查看当前时区2.修改设置Linux服务器时区3.复制相应的时区文件,替换系统时区文件;或者创建链接文件4. 查看和修改Linux的时间5. 硬件时间和系统时间的 相互同步1.背景描述 最近一个项目日期采用java8的LocalDa…...
CSS数据类型以及符号
css数据类型定义的是css属性中具有代表性的值,在规范的语法格式中,使用关键字外加一对 <和>表示,例如数值类型<number>、色值类型<color>等。 举个例子:background-image这个css属性语法结构如下: …...
LeetCode-54. 螺旋矩阵
题目来源 54. 螺旋矩阵 题目思路 while循环只遍历"环",不成环就不遍历了 四个边界 上边界 top : 0下边界 bottom : matrix.length - 1左边界 left : 0右边界 right : matrix[0].length - 1 矩阵不一定是方阵 top < bottom && left < r…...
【Python入门第十八天】Python For 循环
Python For 循环 for 循环用于迭代序列(即列表,元组,字典,集合或字符串)。 这与其他编程语言中的 for 关键字不太相似,而是更像其他面向对象编程语言中的迭代器方法。 通过使用 for 循环,我们…...
Qt图片定时滚动播放器
目录参考结构PicturePlay.promain.cpppictureplay.hpictureplay.cpppictureplay.ui效果源码参考 Qt图片浏览器 QT制作一个图片播放器 Qt中自适应的labelpixmap充满窗口后,无法缩小只能放大 可以显示jpg、jpeg、png、bmp。可以从电脑上拖动图到窗口并显示出来或者打开…...
李宏毅2023春季机器学习课程
目录2021&2022课程重磅须知我维护的其他项目更新日志课程地址课程资料直链课程作业直链其他优质课程2021&2022课程 CSDN Github 重磅须知 为方便所有网课资料与优质电子书籍的实时更新维护,创建一个在线实时网盘文件夹; 网盘获取方式&#…...
计算机操作系统知识点汇总
计算机操作系统选择填空题,300知识点,包含操作系统概论、处理机管理、内存管理、设备管理、文件管理等,为大学生期末创造奇迹提供无限可能 1、填空题 1、操作系统是对计算机资源进行管理的软件 2、操作系统是提供了处理机管理、 存储器管理…...
【离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表】
离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表一、DWD层设计要点二、交易域相关事实表1.交易域加购事务事实表1.加购事务事实表 前期梳理2.加购事务事实表 DDL表设计分析3.加购事务事实表 加载数据分析1.首日全…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
