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

C++ 类和对象篇(五) 析构函数

目录

一、概念

1. 析构函数是什么?

2. 为什么要有析构函数?

3. 怎么用析构函数?

3.1 创建析构函数

3.2 调用析构函数

二、特性

三、由编译器生成的默认析构函数

四、对象的析构顺序

1. 局部对象

2. new出来的堆对象

3. 全局对象


一、概念

1. 析构函数是什么?

        析构函数是一个特殊的成员函数,用来释放对象使用的资源(如关闭文件、释放内存等)。

2. 为什么要有析构函数?

        如何释放对象申请的系统资源?忘记释放怎么办?能不能在销毁对象时自动释放?

举个小例子:
class Test
{
public://构造函数Test(){_arr = (char*)malloc(1024*1024*1024);//申请1G空间}//销毁函数:用于释放资源void Destory(){free(_arr);}
private:char* _arr;
};int main()
{Test* t = new Test;//在堆上创建一个对象delete t;//销毁一个对象while (1) {}return 0;
}如果要销毁Test对象,必须先使用Destory公有方法来释放资源,否则会造成内存泄漏,
这未免有点麻烦,而且容易忘记,那能否在对象销毁的同时释放资源呢?

将以上程序运行起来,对比前后的内存变化,可以发现销毁对象前如果忘记释放资源,就会造成内存泄漏等问题。

程序运行前: 

程序运行后:


        所以为避免C++使用者在销毁对象时忘记释放对象使用的资源的问题,C++引入了析构函数,在析构函数里写释放资源的代码,在对象销毁时编译器会自动调用析构函数释放对象使用的资源。

        析构函数相对于自己写的销毁函数,其优势在于不需要自己去显示调用。 

3. 怎么用析构函数?

3.1 创建析构函数

        创建时要注意析构函数特征:析构函数名是在类名前加上字符~、无参数无返回值。

        类中动态申请的资源需要在析构函数中写相应的代码手动释放。

用以下例子来说明如何创建无参构造函数和带参构造函数:
创建时要注意析构函数特征:析构函数名是在类名前加上字符~、无参数无返回值。
class Test
{
public://构造函数Test(){_arr = (char*)malloc(1024*1024*1024);//申请1G空间}//析构函数:在析构函数里释放资源,对象被销毁时会自动被调用。~Test(){cout << "析构函数调用成功!" << endl;free(_arr);}
private:char* _arr;
};

3.2 调用析构函数

        在对象销毁时编译器会自动调用析构函数。所以析构函数是不需要我们去显示调用的,我们只需要记得销毁对象(特指堆上的对象)即可。

接上面的例子,演示如何调用无参构造函数和带参构造函数:
int main()
{//在堆上创建对象tTest* t = new Test;for (int i = 0; i < 100000; ++i){cout << i << endl;}//销毁对象tdelete t;return 0;
}


二、特性

        再次强调,析构函数的任务不是销毁对象,而是完成对象中资源的清理工作,对象在销毁时会自动调用析构函数。(对象的内置类型的成员变量由系统进行回收,自定义类型的成员变量系统会去调用它的析构函数。

析构函数是特殊的成员函数,其特征如下:

1. 析构函数名是在类名前加上字符~。

2. 无参数无返回值类型。

3. 对象动态申请的资源需要在析构函数中写相应的代码手动释放。

4. 一个类只能有一个析构函数,析构函数不能重载。

5. 若未显式定义,系统会自动生成默认的析构函数。

6. 对象生命周期结束时,C++编译系统系统自动调用析构函数。


三、由编译器生成的默认析构函数

若未显式定义,系统会自动生成默认的析构函数。


那什么时候需要显示的写析构函数,什么时候让编译器自动生成呢?

        有资源申请(如使用malloc动态开辟空间)时,一定要写,否则会造成资源泄漏。如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数。


四、对象的析构顺序

1. 局部对象

        后实例化的对象先析构,先实例化的对象后析构。因为对象是定义在栈帧里面的,而栈帧的建立遵循后进先出。

class A
{
public:~A(){cout << "A被析构" << endl;}
};class B
{
public:~B(){cout << "B被析构" << endl;}
};class C
{
public:~C(){cout << "C被析构" << endl;}
};int main()
{A a;B b;C c;return 0;
}

2. new出来的堆对象

        堆对象的析构发生在使用delete的时候,与delete的使用顺序相关。

int main()
{A* a = new A();B* b = new B();C* c = new C();delete a;delete b;delete c;return 0;
}

3. 全局对象

        在一个源文件中的全局对象,先实例化的对象后析构。

A a;
B b;
C c;int main()
{return 0;
}


------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。

相关文章:

C++ 类和对象篇(五) 析构函数

目录 一、概念 1. 析构函数是什么&#xff1f; 2. 为什么要有析构函数&#xff1f; 3. 怎么用析构函数&#xff1f; 3.1 创建析构函数 3.2 调用析构函数 二、特性 三、由编译器生成的默认析构函数 四、对象的析构顺序 1. 局部对象 2. new出来的堆对象 3. 全局对象 一、概念 1…...

find 与 cp 命令组合使用

查找到文件后&#xff0c;拷贝到指定路径 find ~/Downloads/ -name *.torrent -exec cp {} ~/Downloads/myTorrent \;\;前面有个空格&#xff0c;要注意&#xff0c;这是固定结构&#xff0c;请不要尝试改变 上面命令是在Downloads 目标中查找后缀为torrent所有文件&#xff0…...

用VLD调查VC内存泄漏

一、发现内存泄漏 使用VS2022&#xff0c;发现提示有内存泄漏&#xff0c;检查了所有的new&#xff0c;确认都有相应的delete释放。 Detected memory leaks! Dumping objects -> {1914} normal block at 0x0000021FDFFBD2E0, 48 bytes long.Data: < >…...

【Java 进阶篇】使用 JDBCTemplate 执行 DQL 语句详解

在前面的文章中&#xff0c;我们已经学习了如何使用 Spring 的 JDBCTemplate 执行 DML&#xff08;Data Manipulation Language&#xff09;操作&#xff0c;包括插入、更新和删除操作。现在&#xff0c;让我们来深入了解如何使用 JDBCTemplate 执行 DQL&#xff08;Data Query…...

了解了spring mvc web容器中一个http请求的全过程,能给我们提升多少武力值

继上一篇文章什么&#xff0c;这年头还有人不知道404_cow__sky的博客-CSDN博客后&#xff0c;有些同学发现&#xff0c;学了之后有啥用&#xff0c;有什么实际场景可以用到吗&#xff1f;程序员就是这样&#xff0c;不习惯于纸上谈兵&#xff0c;给一个场景show me code才是最实…...

【BBC新闻文章分类】使用 TF 2.0和 LSTM 的文本分类

一、说明 NLP上的许多创新是如何将上下文添加到词向量中。常见的方法之一是使用递归神经网络...

set和map的封装

目录 介绍 红黑树代码 set insert的迭代器转换问题 为什么会有这样的问题? 如何解决 代码 map 注意点 代码 介绍 set和map的底层都是红黑树,所以我们可以在自己实现的红黑树(简易版)的基础上,进行封装,成为简易的set和map 红黑树代码 #pragma once#include <…...

java基础练习--基础语法

预备知识:Java基本语法、分支、循环、数组和字符串 7-1 累加器 请你实现一个累加器。输入n个非负整数&#xff0c;输出他们的和。 1<n<1000&#xff0c;而每个数则<10000。 输入格式: 输入包括两行。 第一行:包括一个整数n&#xff0c;表示总共有n个数。 第二行:包…...

Android12 OTA编译差分包报错问题

前言 在Ubuntu 20.04.4 LTS系统中编译Android12 OTA差分包的时候提示如下报错log: Warning: releasetools script should be invoked as hermetic Python executable -- build and run ota_from_target_files directly. Traceback (most recent call last):File "./bu…...

现代c++手撸2309神经网络最简化版230901

用c++输入数据:vector<vector<float>> inputs = { {1, 1}, {1, 0} };数据targets={0,1}; 测试:vector<vector<float>> inputs22 = { {1, 0}, {1,1} }; 构建神经网络,例如:NeuralNetwork nn({ 2, 4, 1 }); 则网络有四层、输入层2个节点、输出层1个节…...

Qt之显示PDF文件

之前使用过mupdf库&#xff0c;能够成功显示pdf&#xff0c;但是我用着有BUG&#xff0c;不太理解它的代码&#xff0c;搞了好久都不行。后面又试了其他库&#xff0c;如pdfium、popler、下载了很多例程&#xff0c;都跑不起来&#xff01;后面偶然得知xpdf库&#xff0c;看起来…...

[极客大挑战 2019]FinalSQL - 异或盲注

1、这题的关键是找注入点&#xff0c;如果选择用户名、密码作为输入点就麻烦了 2、注入点&#xff1a;按钮&#xff0c;点击就传id&#xff1b;当id1时&#xff0c;提示Click others   可以利用id的特性&#xff0c;构造异或匹配   payload: f"1^(ord(substr((select…...

【Go语言实战】(25) 分布式算法 MapReduce

MapReduce 写在前面 身为大数据专业的学生&#xff0c;其实大学我也多多少少接触过mapreduce&#xff0c;但是当时觉得这玩意太老了&#xff0c;觉得这和php一样会被时代淘汰。只能说当时确实太年轻了&#xff0c;没有好好珍惜那时候的学习资源… 现在回过头来看mapreduce&a…...

【网络安全-信息收集】网络安全之信息收集和信息收集工具讲解(提供工具)

工具下载百度网盘链接(包含所有用到的工具&#xff09;&#xff1a; 百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.…...

战火使命ssr排名,战火使命角色强度排行

在战火使命中&#xff0c;很多玩家都在关注SSR角色的强度排行&#xff0c;那么&#xff0c;下面就为大家分享一下小编整理的最新战火使命ssr排名&#xff0c;一起来看看吧。 关注【娱乐天梯】&#xff0c;获取内部福利号 一、SSR角色排名榜&#xff1a; 1. 克拉拉、艾蕾娜、杰西…...

CSS之linear-gradient( ) 函数—背景颜色渐变设计

目录 linear-gradient( ) 函数 简介&#xff1a; 语法&#xff1a; 详解&#xff1a; 例如&#xff1a; linear-gradient( ) 函数 简介&#xff1a; linear-gradient 函数是 CSS 中用于创建线性渐变的函数。它接受一个或多个参数&#xff0c;并使用这些参数创建一个渐变。…...

[Unity]未能加载一个或多个断点问题

【背景】 大家2023国庆快乐&#xff0c;虽然是假期&#xff0c;我还是继续码些文章。 今天写项目时遇到个环境问题&#xff0c;新建脚本时双击调起VS编辑器&#xff0c;忽然提示无法加载一个或多个断点&#xff08;当时忘记截图了&#xff0c;现在已解决&#xff0c;就不上图了…...

Qt中的基础数据类型

1.基础类型 因为Qt是一个C++ 框架, 因此C++中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型 QT基本数据类型定义在#include <QtGlobal> 中,QT基本数据类型有: 类型名称注释备注qint8signed ch…...

2023阿里云域名优惠口令大全

2023年阿里云域名优惠口令&#xff0c;com域名续费优惠口令“com批量注册更享优惠”&#xff0c;cn域名续费优惠口令“cn注册多个价格更优”&#xff0c;cn域名注册优惠口令“互联网上的中国标识”&#xff0c;阿里云优惠口令是域名专属的优惠码&#xff0c;可用于域名注册、续…...

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...