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

C++基础语法:析构函数

前言

      "打牢基础,万事不愁" .C++的基础语法的学习."学以致用,边学边用",编程是实践性很强的技术,在运用中理解,总结.

引入

        用一个简单的例子,分析析构函数的工作过程.以<C++ Prime Plus> 6th Edition(以下称"本书")内容做参考.

回顾类的默认函数

        类的默认函数及用途如下:

                 构造函数:给属性赋值

                复制构造函数:用已有对象初始化新对象,对象之间传递属性值

                赋值符:类似于复制构造函数,传递值.

                析构函数:删除对象属性

        既然是默认函数,表示可以重载.如果没有属性,构造函数没有重载必要;复制构造函数和赋值符重载前面已解读过,应用场景是深复制中处理静态数据,以及复制指针原有的数据.这里主要是说析构函数的重载.

回顾new和delete

        new的含义:在堆空间上开辟内存空间,返回指向该内存空间首地址的指针

        delete的含义:释放new所指向的内存空间

        new的格式:

       指针类型 指针名=new 数据类型[元素个数];   //生成n个元素的数组,返回指针 

       指针类型 指针名=new 数据类型;                     //指向单个元素,返回指针 

int *par=new int[5];       //par指向一个整型数组的指针
int *p=new int;            //p指向一个int类型变量

        可以在后面用{}加上该种数据类型的值

        指针类型 指针名=new 数据类型[元素个数]{值列表(用逗号分开)};   

       指针类型 指针名=new 数据类型{单个值};     

int *par=new int[5]{1,2,3,4,5};       //生成指向整型数组的指针并赋值
int *p=new int{3};                    //生成指向单个整型值3的指针
=============
int b=par[1];                         //par[1]值为2,间接访问数组
int c=*p;                             //*p的值为3,间接访问数据

             delete的格式:和new相对应,当new生成的指针指向数组,用[],否则不用

delete[] par;    //释放par指向的内存空间
delete p;        //释放p指向的内存空间

析构函数的重载

        下面用一个简单例子来说明:

#include<iostream>
using namespace std;class Demo {                                        //Demo类int* pint;
public:Demo(int* d):pint(d){}~Demo() { delete pint; }						//析构函数,注释看效果
};class OutDemo {                                    //OutDemo类Demo* demo;
public:OutDemo (Demo * d)  : demo(d) {}~OutDemo() { delete demo; }						//析构函数,注释看效果
};

        测试代码:

int main(void) {int* pval = new int{ 3 };						//new生成整型指针Demo* pd = new Demo(pval);						//new生成Demo对象,返回指针OutDemo* pod = new OutDemo(pd);					//new生成OutDemo对象,返回指针cout << "调用析构函数前的值为:" << *pval << endl;cout << "调用析构函数前的地址为:" << pval << endl;delete pod;										//释放内存cout << "调用析构函数后的值为:" << *pval << endl;cout << "调用析构函数后的地址为:" << pval << endl;}

        说明:分别注释两个重载的析构函数,可以看出不同.下面分析

析构函数的调用过程

        1>使用默认析构函数.

        此时上面两个类中的析构函数应处于注释状态.当调用delete pod;时, 调用默认析构函数,

~OutDemo() {};	        //默认析构函数

        按照默认构造函数的定义,对象中属性被删除,即数据类型Demo*,变量demo的表示的值-----pd被删除,而pd指向的数据pval未删除.所以打印出来的结果*pval仍然等于3.

        2>使用重载析构函数

        此时上面两个类定义的析构函数应处于非注释状态.当调用delete pod;时,调用重载析构函数

~OutDemo() { delete demo; }  

        重载析构函数实际上有两个部分,一是调用默认析构函数,把对象中的属性pd删除(与上面一条相同)二调用delete demo;------他的含义是调用Demo的析构函数,此时对应语句是:

~Demo() { delete pint; }

        此时再重复上一种状况,一删除对象属性pval,二调用delete pint,释放整型指针pint指向的空间,删除其数据,所以打印*pval的结果已发生改变.

        有一个细节:当传递进去的指针不是new生成时,会报错,如把int* pval = new int{ 3 };改成

int a=3;
int *pval=&a;

        运行后产生异常. 说明new和delete需配合使用

析构函数的小结

        默认析构函数做了什么? 删除属性

        重载析构函数做了什么?一调用默认析构函数;二根据内容操作.

        重点:当调用"delete 对象指针名"时,执行析构函数 .如果是默认析构函数则只删除属性,如果重载了析构函数先删除属性,再执行其他内容.

        优点:只要是传入的指针((new生成),在析构函数上加上删除语句(如delete p;),释放内存空间.而对象和他包含的对象之间是各自独立的.如delete pod;释放了最初传入的整型指针pval

        应用场景:对内存空间要求比较高时,不然传对象引用就可以了.在笔者另一篇帖子里C++基础语法:复制构造函数,赋值构造函数及浅复制,深复制_复制构造和赋值-CSDN博客有介绍

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【现代操作系统】1. intro
  • Java中的主要设计模式
  • ubuntu18.04下安装nvidia3090显卡驱动
  • 数据结构----栈
  • C语言指针详解-上
  • (七)Activiti-modeler中文支持
  • 『Z-Workshop』 The Graph workshop mini hackathon活动
  • IBERT 眼图机制
  • 使用Poi-tl对word模板生成动态报告
  • 利用 Python 的包管理和动态属性获取(`__init__.py` 文件和 `getattr` 函数)特性来实现工厂方法模式
  • RHEL8 配置epel源
  • 深入探讨C语言中的高级指针操作
  • 生产环境中MapReduce的最佳实践
  • 微信小程序在不同移动设备上的差异导致原因
  • Startup-SBOM:一款针对RPM和APT数据库的逆向安全工具
  • Cookie 在前端中的实践
  • GraphQL学习过程应该是这样的
  • java8 Stream Pipelines 浅析
  • js继承的实现方法
  • PHP的类修饰符与访问修饰符
  • React-redux的原理以及使用
  • 大数据与云计算学习:数据分析(二)
  • 电商搜索引擎的架构设计和性能优化
  • 读懂package.json -- 依赖管理
  • 工作中总结前端开发流程--vue项目
  • 基于遗传算法的优化问题求解
  • 力扣(LeetCode)22
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 如何设计一个比特币钱包服务
  • 少走弯路,给Java 1~5 年程序员的建议
  • 《天龙八部3D》Unity技术方案揭秘
  • linux 淘宝开源监控工具tsar
  • 扩展资源服务器解决oauth2 性能瓶颈
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • # 达梦数据库知识点
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (0)Nginx 功能特性
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (译) 函数式 JS #1:简介
  • (最新)华为 2024 届秋招-硬件技术工程师-单板硬件开发—机试题—(共12套)(每套四十题)
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET C# 操作Neo4j图数据库
  • .NET Standard 的管理策略
  • .net 连接达梦数据库开发环境部署
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [240812] X-CMD 发布 v0.4.5:更新 gtb、cd、chat、hashdir 模块功能
  • [C++] 容器适配器:深入理解Stack与Queue的底层原理
  • [C语言]编译和链接