C++对象模型(13)-- 构造函数语义学:析构函数

1、默认析构函数生成规则

跟构造函数一样,编译器不一定会为类生成默认析构函数。生成默认析构函数的规则有下面2条:

(1)包含一个类类型的成员变量,且成员变量所属的类有默认析构函数。

(2)其父类有默认析构函数。

我们可以通过VS2019的反汇编代码来验证这2条规则:

class Base {
public:~Base(){}
};class Derive: public Base{
};int main()
{Derive derive;return 0;
}

反汇编窗口中的代码如下:

2、继承中的析构函数

继承中的析构顺序跟构造顺序相反:由外而内,即先析构子类对象,再析构父类对象,整个过程就跟剥洋葱一样。

我们可以用这个例子验证析构顺序:

class Base {
public:~Base() {std::cout << "~Base" << std::endl;}
};class Derive : public Base {
public:~Derive(){std::cout << "~Derive" << std::endl;}
};int main()
{Derive derive;return 0;
}

程序运行结束后,打印:

~Derive

~Base

3、虚析构函数

基类对派生类及其对象的操作,只能影响到那些从基类继承下来的成员。如果要用基类对继承成员进行操作,则要把基类的这个成员函数定义为虚函数,析构函数同样需要如此。

用基类指针来删除派生类的对象,而这个基类的析构函数不是虚函数,则对象的派生部分不会被销毁,这会导致内存泄露。

class Base {
public:~Base() { std::cout << " ~Base" << std::endl;}
};class Derive : public Base {
public:~Derive(){std::cout << " ~Derive" << std::endl;}
};int main()
{Base *pb = new Derive();delete pb;return 0;
}

程序运行后输出:~Base

没有调用Derive类的析构函数。

要解决这个内存泄漏问题,只需要把基类的析构函数改成虚析构函数就可以了:

virtual ~Base(){};

4、多重继承时的析构函数

修改上面的代码,增加一个类Base2:

class Base2 {};

并让Derive继承这个类Base2:

class Derive : public Base, public Base2 {}

现在这个类Derive的对象布局是这样的:

我们在main()函数里添加如下代码:

int main()
{Base2 *pb2 = new Derive();delete pb2;return 0;
}

执行代码后发现报错。是什么原因呢?

因为现在pb2指向的是类Base2对象,执行delete时就必须把整个类Derive对象给删除,现在只删除了部分对象,肯定是不行的。那么怎么delete整个类Derive对象呢?

把类Base2的析构函数写成虚析构函数:

virtual ~Base2(){};

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

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

相关文章

14. Java多线程基础

Java —— 多线程 1. 线程与进程1.1 线程生命周期1.2 线程优先级 2. 多线程2.1 守护线程2.2 多线程高并发2.3 synchronized同步锁2.4 synchronized互斥锁 1. 线程与进程 进程&#xff08;Process&#xff09; 操作系统进行资源分配和调度的基本单位&#xff1a;系统中正在运行的…

【网络协议】聊聊从物理层到MAC层 ARP 交换机

物理层 物理层其实就是电脑、交换器、路由器、光纤等。组成一个局域网的方式可以使用集线器。可以将多台电脑连接起来&#xff0c;然后进行将数据转发给别的端口。 数据链路层 Hub其实就是广播模式&#xff0c;如果A电脑发出一个包&#xff0c;B、C电脑也可以收到。那么数据…

[uni-app] canvas绘制圆环进度条

文章目录 需求参考链接基本问题的处理1:画布旋转的问题2:注意arc()的起始位置是3点钟方向3: 如果绘制1.9*Matn.PI的圆环, 要保证其实位置在0点方向?4:小线段怎么画, 角度怎么处理? 源码 需求 要绘制一个如此的进度条 参考链接 uni-app使用canvas绘制时间刻度以及不显示问…

4.Vue-Vue调用第三方接口

题记 用vue调用第三方接口&#xff0c;以下是全部代码和操作流程。 寻找第三方接口网站 推荐&#xff1a;免费API - 提供免费接口调用平台 (aa1.cn) 下面的代码以下图中的接口为例 安装axios模块 在终端输入以下命令&#xff1a; npm install axios 调用第三方接口代码 调…

从入门到进阶 之 ElasticSearch 节点配置 集群篇

&#x1f339; 以上分享 ElasticSearch 安装部署&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#x1f431;‍&a…

Spring框架(三)

1、代理模式&#xff1a; 二十三种设计模式中的一种&#xff0c;属于结构型模式。它的作用就是通过提供一个代理类&#xff0c;让我们在调用目标方法的时候&#xff0c;不再是直接对目标方法进行调用&#xff0c;而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标…

如何让大模型自由使用外部知识与工具

本文将分享为什么以及如何使用外部的知识和工具来增强视觉或者语言模型。 全文目录&#xff1a; 1. 背景介绍 OREO-LM: 用知识图谱推理来增强语言模型 REVEAL: 用多个知识库检索来预训练视觉语言模型 AVIS: 让大模型用动态树决策来调用工具 技术交流群 建了技术交流群&a…

【灵动 Mini-G0001开发板】+Keil5开发环境搭建+ST-Link/V2程序下载和仿真+4颗LED100ms闪烁。

我们拿到手里的是【灵动 Mini-G0001开发板】 如下图 我们去官网下载开发板对应资料MM32G0001官网 我们需要下载Mini—G0001开发板的库函数与例程&#xff08;第一手学习资料&#xff09;Keil支持包&#xff0c; PCB文件有需要的&#xff0c;可以自行下载。用户指南需要下载&a…

Linux网络-UDP/TCP协议详解

Linux网络-UDP/TCP协议详解 2023/10/17 14:32:49 Linux网络-UDP/TCP协议详解 零、前言一、UDP协议二、TCP协议 1、应答机制2、序号机制3、超时重传机制4、连接管理机制 三次握手四次挥手5、理解CLOSE_WAIT状态6、理解TIME_WAIT状态7、流量控制8、滑动窗口 丢包问题9、拥塞控制…

探索音频传输系统:数字声音的无限可能 | 百能云芯

音频传输系统是一项关键的技术&#xff0c;已经在数字时代的各个领域中广泛应用&#xff0c;从音乐流媒体到电话通信&#xff0c;再到多媒体制作。本文将深入探讨音频传输系统的定义、工作原理以及在现代生活中的各种应用&#xff0c;以帮助您更好地了解这一重要技术。 音频传输…

接口加密解决方案:Python的各种加密实现!

01、前言 在现代软件开发中&#xff0c;接口测试已经成为了不可或缺的一部分。随着互联网的普及&#xff0c;越来越多的应用程序都采用了接口作为数据传输的方式。接口测试的目的是确保接口的正确性、稳定性和安全性&#xff0c;从而保障系统的正常运行。 在接口测试中&…

通过商品ID查询天猫商品详情数据,可以拿到商品标题,商品价格,商品库存,商品销量,商品sku数据等,天猫API接口

通过商品ID查询天猫商品详情数据可以用淘宝开放平台的淘宝客商品详情查询接口&#xff08;taobao.tbk.item.info.get&#xff09;来完成。 首先需要申请一个淘宝开放平台的应用&#xff0c;并获取到App Key和App Secret&#xff0c;然后使用淘宝开放平台的淘宝客商品详情查询接…