【C++】类和对象(4)--析构函数

一 概念

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作(Destroy).

二 特性

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

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

class A
{
public:
    A(int value)//构造函数
    {
        i = value;
    }
    ~A()//析构函数   
    {
        
    }
private:
    int i;
};

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

3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构

函数不能重载

class C
{
public:
	~C() { }
	~C(int i) { }    // error C2524: “C”: 析构函数 必须有“void”参数列表
	// warning C4523: “C”: 指定了多个析构函数
};

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

析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作。

内置成员不做处理

自定义成员自动调用它的析构函数

class Stack
{
public:
       Stack(size_t capacity = 3)
       {
              cout << "Stack(size_t capacity = 3)" << endl;

              _a = (int*)malloc(sizeof(int) * capacity);
              if (nullptr == _a)
              {
                      perror("malloc申请空间失败!!!");
              }

              _capacity = capacity;
              _top = 0;
       }

       ~Stack()//析构函数
       {
              cout << "~Stack()" << endl;

              free(_a);
              _capacity = _top = 0;
              _a = nullptr;
       }

private:
       int* _a;
       int _capacity;
       int _top;
};

class MyQueue
{
       // 默认生成析构函数,行为跟构造类似
       // 内置类型成员不做处理
       // 自定义类型成员会去调用他的析构
private:
       Stack _pushst;
       Stack _popst;
       int _size = 1;
};

int main()
{
       //Stack st1;
       MyQueue mq;

       return 0;
}

如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如 Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。 

5 构造顺序是按照语句的顺序进行构造,析构是按照构造的相反顺序进行析构

构造函数用于对对象中的变量赋初值,析构函数用于释放所定义的对象的所有内存空间。构造函数和析构函数都不需要用户调用的,构造函数在定义对象时自动调用,析构函数当对象的生存期结束的时候会自动的调用。一般来说,析构函数的调用顺序与构造函数相反。但对象存储类型可以改变析构函数的调用顺序。
全局范围中定义的对象的构造函数在文件中的任何其他函数(包括main)执行之前调用(但不同文件之间全局对象构造函数的执行顺序是不确定的)。全局变量是需要在进入main()函数前即初始化的,所以在一个程序中一个全局变量的构造函数应该是第一个被调用的,比main()函数都要早同时全局对象又必须在main()函数返回后才被销毁,当main终止或调用exit函数时调用相应的析构函数,所以它的析构函数是最后才被调用。
当程序执行到对象定义时,调用自动局部对象的构造函数。该对象的析构函数在对象离开范围时调用(即离开定义对象的块时)。自动对象的构造函数与析构函数在每次对象进人和离开范围时调用。
static局部对象的构造函数只在程序执行首次到达对象定义时调用一次,对应的析构函数在main终止或调用exit函数时调用。

class A
{
public:
    A(int value)
    {
        i = value;
        cout << "Object " << i << " constructor";
    }
    ~A()    // destructor
    {
        cout << "Object " << i << " destructor" << endl;
    }
private:
    int i;
};

A first(1);  // global object全局变量

void func()
{
    A fifth(5);
    cout << " (local automatic in create)" << endl;
    static A sixth(6);
    cout << " (local static in create)" << endl;
    A seventh(7);
    cout << " (local automatic in create)" << endl;
}
int main()
{
    cout << " (global created before main)" << endl;

    A second(2);
    cout << " (local automatic in main)" << endl;

    static A third(3);  // local object
    cout << " (local static in main)" << endl;

    func();     // call function to create objects
    A fourth(4);      // local object
    cout << " (local automatic in main)" << endl;
    return 0;
}

 下面总结下不同存储类型构造函数和析构函数的调用。

构造函数的调用:
(1)全局变量:程序运行前;
(2)函数中静态变量:函数开始前;
(3)函数参数:函数开始前;
(4)函数返回值:函数返回前;
析构函数的调用:
(1)全局变量:程序结束前;
(2)main中变量:main结束前;
(3)函数中静态变量:程序结束前;
(4)函数参数:函数结束前;
(5)函数中变量:函数结束前;
(6)函数返回值:函数返回值被使用后;

 对于相同作用域和存储类别的对象,调用析构函数的次序正好与调用构造函数的次序相反

本节内容相对简单, 但是和构造函数有一定联系, 对构造函数基础不太好的可以去我博客【C++】类和对象(2)--构造函数-CSDN博客

【C++】类和对象(3)--初始化列表(再谈构造函数)-CSDN博客

继续加油!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库操作入门:PyMongo 和 MongoDB 的基本用法

MongoDB MongoDB是一种流行的NoSQL数据库&#xff0c;它将数据存储在类似JSON的文档中&#xff0c;使数据库非常灵活和可扩展 PyMongo Python需要一个MongoDB驱动程序来访问MongoDB数据库。在本教程中&#xff0c;我们将使用MongoDB驱动程序 “PyMongo”。建议使用PIP来安装…

清理mac苹果电脑磁盘软件有哪些免费实用的?

苹果电脑是一款非常流行的操作系统设备&#xff0c;其稳定性和性能一直备受用户的喜爱。然而&#xff0c;随着时间的推移&#xff0c;我们使用电脑的过程中可能会发现磁盘上存储的数据越来越多&#xff0c;这不仅占用了宝贵的硬盘空间&#xff0c;还可能导致电脑运行变慢。因此…

GreenCloud VPS 重装系统后无法 SSH 的解决方法

发布于 2023-07-17 在 https://chenhaotian.top/vps/greencloud-ssh-fix/ 解决方法 发工单让客服解决即可。 操作过程 Tu Pham Operator 客服 Hello, We have fixed your problem, please try again! Thanks! Tu Pham, Senior Technician - GreenCloudVPS 17th July 2023…

Java Stream 的使用

Java Stream 的使用 开始中间操作forEach 遍历map 映射flatMap 平铺filter 过滤limit 限制sorted 排序distinct 去重 结束操作collect 收集toList、toSet 和 toMapCollectors.groupingByCollectors.collectingAndThen metch 匹配find 查询findFirst 与 findAny 的使用Optional …

Ubuntu 和 Windows 文件互传

FTP 服务 FTP 采用 Internet 标准文件传输协议 FTP 的用户界面&#xff0c; 向用户提供了一组用来管理计算机之间文件传输的应用程序。在开发的过程中会频繁的在 Windows 和 Ubuntu 下进行文件传输&#xff0c;比如在 Windwos 下进行代码编写&#xff0c;然后将编写好的代码拿到…

计算机操作系统—经典同步问题

经典同步问题 1.生产者与消费者问题 1.1.问题概述 在现实生活中&#xff0c;当我们缺少某些生活用品时&#xff0c;就会到超市去购买。当你到超市时&#xff0c;你的身份就是消费者&#xff0c;那么这些商品又是哪里来的呢&#xff0c;自然是供应商&#xff0c;那么它们就是生…

Java 入门基础题

目录 1.输出一个整数的每一位 2.判定素数 3.求最大值方法的重载 4.输出闰年 5.打印 X 图形 6.数字9 出现的次数 7.计算分数的值 8. 模拟登陆 9.使用函数求最大值 10.斐波那契数列 星光不负赶路人&#xff0c;加油铁子们&#xff01;&#xff01;&#xff01; 1…

【开源】基于Vue.js的快递管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

docker入门,这一篇就够了。

Docker入门&#xff0c;这一篇就够了。 Docker容器虚拟化平台。 前言 接触docker很长时间了&#xff0c;但是工作中也没有用到&#xff0c;所以总是学了忘&#xff0c;忘了学。不过这次&#xff0c;我打算跟大家分享一下我的学习历程&#xff0c;也算是我的独特的复习笔记&…

Easymesh前言介绍

1.什么是Easymesh 什么是Easymesh&#xff0c;这里需要介绍到有3个点&#xff0c;分别是WFA、MAP和Easymesh认证。 WFA是Wi-Fi 联盟&#xff0c;Wi-Fi 联盟是专门针对 Wi-Fi 主题的标准创建机构&#xff0c;并且制定新标准&#xff0c;在 Wi-Fi 基础上提供可用功能&#xff0c…

Windows conan环境搭建

Windows conan环境搭建 1 安装conan1.1 安装依赖软件1.1.1 python安装1.1.2 git bash安装1.1.3 安装Visual Studio Community 20191.1.3.1 选择安装的组件1.1.3.2 选择要支持的工具以及对应的SDK 1.1.4 vscode安装 1.3 验证conan功能1.4 查看conancenter是否包含poco包1.5 查看…

Linux shell编程学习笔记25:tty

1 tty的由来 在 1830 年代和 1840 年代&#xff0c;开发了称为电传打字机&#xff08;teletypewriters&#xff09;的机器&#xff0c;这些机器可以将发件人在键盘上输入的消息“沿着线路”发送在接收端并打印在纸上。 电传打字机的名称由teletypewriters&#xff0c; 缩短为…

程序员月入过万的秘密,赶快收藏史上最靠谱接单攻略!!!

近几年经济十分不景气&#xff0c;无论是哪一行总是面临着生活的不容易。不少人都选择多干几份工作来养家糊口&#xff0c;保证家人的生活。那么咱们程序员该如何是好呢&#xff1f;相信不少人已经有了答案&#xff0c;那就是网上接单&#xff01;那么本期就让小编带你一起来看…

论文阅读:Robust High-Resolution Video Matting with Temporal Guidance

发表时间&#xff1a;2021年8月25日 项目地址&#xff1a;https://peterl1n.github.io/RobustVideoMatting/ 论文地址&#xff1a;https://arxiv.org/pdf/2108.11515.pdf 我们介绍了一种鲁棒的&#xff0c;实时的&#xff0c;高分辨率的人体视频匹配方法&#xff0c;以实现了新…

No205.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【C++】类与对象 I

类与对象 I &#xff1a; 前言&#xff1a;&#xff08;C&#xff09;面向过程 和&#xff08;C&#xff09;面向对象 初步认识前言&#xff1a;类的引入一、类的介绍二、类的定义&#xff08;一&#xff09;class 语法&#xff08;二&#xff09;类的两种定义方式&#xff1a;…

【Qt之QWizard】使用1

QWizard使用 描述方法枚举&#xff1a;enum QWizard::WizardButton枚举&#xff1a;enum QWizard::WizardOption枚举&#xff1a;enum QWizard::WizardStyle枚举&#xff1a;enum QWizard::WizardPixmap常用成员方法槽函数信号 示例设置标题添加page页设置按钮文本设置自定义按…

IntelliJ IDEA cmd和idea Terminal查看java版本不一致

参考&#xff1a;IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解决方案 1、idea清缓存重启 没用 2、删除缓存文件 没试 3、修改环境变量的顺序 没试 4、重启电脑 麻烦&#xff0c;没试 5、项目配置jdk7 没试 按照这个url配置了一个遍 https://blog.csdn…

【电路笔记】-诺顿定理(Norton‘s Theorem)

诺顿定理&#xff08;Norton’s Theorem&#xff09; 文章目录 诺顿定理&#xff08;Nortons Theorem&#xff09;1、概述与定义2、诺顿模型确定3、一些线性电路的诺顿模型3.1 单电压源3.2 单电流源3.3 多电流/电压源 5、总结 本文是我们上一篇有关戴维南定理的文章的延续。 在…

Netty+SpringBoot 打造一个 TCP 长连接通讯方案

项目背景 最近公司某物联网项目需要使用socket长连接进行消息通讯&#xff0c;捣鼓了一版代码上线&#xff0c;结果BUG不断&#xff0c;本猿寝食难安&#xff0c;于是求助度娘&#xff0c;数日未眠项目终于平稳运行了&#xff0c;本着开源共享的精神&#xff0c;本猿把项目代码…