析构函数、拷贝构造
1、析构函数
析构函数的定义方式
函数名和类名相同,在类名前加~,没有返回值类型,没有函数形参(不能重载)
当对象生命周期结束的时候,系统会自动调用析构函数
先调用析构函数,再释放对象的空间
析构函数实现
#include <iostream>using namespace std;
class Person
{
private:int mAge;
public://无参构造Person(){cout<<"无参构造:"<<endl;}//无参构造Person(int age){mAge = age;cout<<"有参构造:"<<mAge<<endl;}//没有 void 和返回值~Person(){cout<<"析构函数:"<<mAge<<endl;}
};void test(){Person(20);{Person(30);}Person(40);
}int main(int argc, char *argv[])
{Person p1(10);test();return 0;
}
构造函数和析构函数的执行次序(面试题)

说白了函数从上到下执行,先执行到的先进栈,先执行有参或者无参构造,后退栈的后执行,执行析构函数
一般情况下,空的析构函数就足够,但是如果一个类有指针成员,这个类必须写析构函数,释放指针成员所指向空间
因为一个对象结束,系统默认回收的是这个对象本身的空间,但是它不会回收这个对象中指针成员指向的空间,所以如果一个类有指针成员,这个类必须写析构函数,释放指针成员所指向空间
#include <iostream>
#include <string.h>
#include <stdlib.h>using namespace std;
class Person
{
private:char *mName;
public:Person(){mName = NULL;}Person(char *name){mName = new char [strlen(name)+1]; //申请堆区空间strcpy(mName,name);cout<<"有参构造:"<<mName<<endl;}//没有 void 和返回值~Person(){if(mName != NULL){delete [] mName;cout<<"释放 Person 类的指针成员所指行向的 堆区空间"<<endl;}}
};int main(int argc, char *argv[])
{Person ml("ml");return 0;
}
最后调用析构函数释放掉 Person 类的指针成员所指行向的 堆区空间

2、拷贝构造
实现拷贝构造
//Person类中的深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1]; //申请堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}Person ml("ml");
Person m = ml; //深拷贝
拷贝构造本质是构造函数
在上面的代码中,旧对象给新对象初始化就会调用拷贝构造函数,ob就是旧对象的引用
系统默认的拷贝是浅拷贝,能完成基本的赋值操作,一旦实现了拷贝构造函数必须实现赋值操作,因为系统默认的函数以及无效了
const Person &ob 代表的是当前类的常引用,因为我们不希望改变参数值,所以是 const 类型的
实现深拷贝的必要性

当执行下面的代码的时候,新对象 m 中的成员指针 和 旧对象 ml 中的成员指针都会指向 堆区空间字符串为 “ml”的地址,那么 ml 在结束的时候会调用析构函数释放掉该堆区空间,而 m 在结束的时候也会调用析构函数释放掉该堆区空间
Person ml("ml");
Person m = ml; //深拷贝所以上面的情况就是,新旧对象中的指针成员指向同一块堆区空间,于是新旧对象对同一块堆区空间释放掉了两次,造成了堆区空间的多次释放,这就是浅拷贝存在的问题
这个时候就需要使用到深拷贝,让新对象中的指针成员指向新的堆区空间,那么新旧对象释放的时候就不会多次释放同一块堆区空间,这就解决了浅拷贝存在的问题

//Person类中的深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1]; //新对象申请属于自己的堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}#include <iostream>
#include <string.h>
#include <stdlib.h>using namespace std;
class Person
{
private:char *mName;
public://无参构造Person(){mName = NULL;}//有参构造Person(char *name){mName = new char [strlen(name)+1]; //申请堆区空间strcpy(mName,name);cout<<"有参构造:"<<mName<<endl;}//深拷贝Person(const Person &ob){mName = new char [strlen(ob.mName)+1]; 新对象申请属于自己的堆区空间strcpy(mName,ob.mName);cout<<"有参构造:"<<ob.mName<<endl;}//析构函数~Person(){if(mName != NULL){delete [] mName;mName = NULL;cout<<"释放 Person 类的指针成员所指行向的 堆区空间"<<endl;}}
};int main(int argc, char *argv[])
{Person ml("ml");Person m = ml; //深拷贝return 0;
}
3、注意事项
析构函数没有 void 和 返回值
如果用户定义了有参构造或者拷贝构造,都会屏蔽系统默认无参构造,所以这种情况最好是有自定义的无参构造,不会编译会出错
如果用户定义了有参构造或者无参构造,不会屏蔽拷贝构造
默认的拷贝都是浅拷贝(能完成基本的操作)
如果类中没有指针成员,不用实现构造拷贝和析构函数
如果类中有指针成员而且指向堆区空间,必须实现析构函数释放指针成员指向的堆区空间,必须实现拷贝构造完成深拷贝动作
相关文章:
析构函数、拷贝构造
1、析构函数析构函数的定义方式函数名和类名相同,在类名前加~,没有返回值类型,没有函数形参(不能重载)当对象生命周期结束的时候,系统会自动调用析构函数先调用析构函数,再释放对象的空间析构函…...
光学镜头是制作过程阶段理解
光学镜头是由多组镜片组合而成,它是摄影机投影一及显微镜上必不可少的部件。那么光学镜头是如何制造的呢?光学镜头的制作分为以下四个阶段:第一、首先将一大块光学玻璃用钻石锯片进行切片,然后用钻头在每一块玻璃切片上钻出多块冰…...
实验室设计|实验室设计要点SICOLAB
一、实验室设计规划要素1、实验室布局:实验室的布局要符合实验室工作流程,可以将实验室划分为干净区和污染区,以确保实验室的卫生和实验的准确性。2、设备选购:根据实验需要选择适当的设备,并确保设备的质量和性能符合…...
I.MX6ULL_Linux_系统篇(16) uboot分析-启动流程
原文链接:I.MX6ULL_系统篇(16) uboot分析-启动流程 – WSY Personal Blog (cpolar.cn) 前面我们详细的分析了 uboot 的顶层 Makefile,了解了 uboot 的编译流程。本章我们来详细的分析一下 uboot 的启动流程,理清 uboot 是如何启动的。通过对 …...
【C#】async关键字修饰后有无await的影响
文章目录测试总结拓展:js的async await问题参考测试 来自微软官网的说法: 异步方法通常包含 await 运算符的一个或多个匹配项,但缺少 await 表达式不会导致编译器错误。 如果异步方法未使用 await 运算符标记悬挂点,则该方法将作…...
Interspeech2022 | 一种基于元辅助学习的低资源口语语义理解方法
中国移动研究院首席科学家冯俊兰博士带领人工智能与智慧运营中心语音团队共同撰写的文章《Meta Auxiliary Learning for Low-resource Spoken Language Understanding》被语音国际顶会Interspeech2022接收。 关于Interspeech Interspeech 是国际最大且最全面关于言语科学与技…...
File类的用法和InputStream,OutputStream的用法
这里写自定义目录标题一、File类1.构造方法2.普通方法二、InputStream1.方法2.FileInputStream3.Scanner类的应用三、OutputStream1.方法2.FileOutputStream3.PrintWriter类的应用一、File类 1.构造方法 签名说明File(File parent, Stringchild)根据父目录 孩子文件路径&…...
Java多线程——Thread类的基本用法
一.线程的创建继承Thread类//继承Thread类class MyThread extends Thread{Overridepublic void run() {System.out.println("线程运行的代码");} } public class Demo1 {public static void main(String[] args) {MyThread t new MyThread();t.start();//启动线程&a…...
【C++】类和对象练习——日期类的实现
文章目录前言1. 日期的合法性判断2. 日期天数(/)2.1 和的重载2.2 对于两者复用的讨论3. 前置和后置重载4. 日期-天数(-/-)5. 前置- -和后置- -的重载6. 日期-日期7. 流插入<<重载8. 流提取>>重载9. 总结10. 源码展示前…...
[LeetCode周赛复盘] 第 333 场周赛20230219
[LeetCode周赛复盘] 第 333 场周赛20230219 一、本周周赛总结二、 [Easy] 6362. 合并两个二维数组 - 求和法1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6365. 将整数减少到零需要的最少操作数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6364. 无平方子集计数1. 题目描…...
数字化时代,如何做好用户体验与应用性能管理
引言 随着数字化时代的到来,各个行业的应用系统从传统私有化部署逐渐转向公有云、行业云、微服务,这种变迁给运维部门和应用部门均带来了较大的挑战。基于当前企业 IT 运维均为多部门负责,且使用多种运维工具,因此,当…...
Python爬虫(7)selenium3种弹窗定位后点击操作,解决点击登录被隐藏iframe无法点击的登陆问题
之前的文章有关于更多操作方式详细解答,本篇基于前面的知识点进行操作,如果不了解可以先看之前的文章 Python爬虫(1)一次性搞定Selenium(新版)8种find_element元素定位方式 Python爬虫(2)-Selenium控制浏览…...
如何对项目健康度进行测量?评估项目健康状况
项目驱动变革,大部分公司逐步由运营驱动转变为项目驱动,带来更多重新和商业价值。对组织而言,从商业角度看,项目旨在推动组织从一个状态转到另一个状态,从而达成特定目标。项目的健康情况如何关乎项目和变革的成本&…...
美国原装二手keysight E4980A(安捷伦)2MHZ LCR表
Agilent E4980A、Keysight E4980A、LCR 表,20 Hz - 2 MHz E4980A 是 Agilent 的 2 MHz LCR 表。LCR表是一种电子测试设备,用于测量电子元件的电感(L)、电容(C)和电阻(R)。LCR 表可…...
《clean coder》:关于摆烂,争论和心态
“凡是不能在五分钟之内解决的争论,都不能依靠辩论解决” ---- Kent Beck 作为一个码农,我并不是一个喜欢争论的角色。很长一段时间会陷入一种摆烂的,被动的状态。“既然其他人想要这么做,就这么办吧”。这可能是非专业的行为中最…...
jenkins下载与简单使用
1.jenkins下载 因为我仍然使用的是jdk1.8进行开发,所以我下载的是jenkins2.332.1版本(jenkins2.346.1版本在2022年末不再支持java8,如果项目使用的是jdk11可以继续使用该jenkins版本),更多版本下载请点击jenkins下载 …...
3|物联网控制|计算机控制-刘川来胡乃平版|第3章:计算机总线技术 补充串行总线部分|课堂笔记|ppt
2022年 10月 10日 3.3 外部总线 3.3.2 RS-232-C总线 机械特性...
Blazor入门100天 : 身份验证和授权 (3) - DB改Sqlite
目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…...
阅读源码和查看官方文档,是解决问题最高效的办法。
作为一个工作8年的老程序员告诉你:阅读源码和查看官方文档,是解决问题最高效的办法。不信你来看,这个困扰了读者半天的问题我查了源码和文档后瞬间解决。 前言 上周五有位读者私信我一个问题,说困扰了他半天,研究了一…...
云原生流量管理系统中 Service , Ingress 和 Endpoint 的关系
摘要 Kubernetes(简称 K8s)是一个用于容器编排和管理的开源平台,其中流量管理是 K8s 的重要功能之一。K8s 提供了多种流量管理方式,以便对不同场景下的流量进行控制和管理。以下是 K8s 中常用的流量管理系统: Service:Service 是 K8s 中最基本的流量管理方式,用于提供…...
Linux驱动开发实战:内核日志与寄存器操作指南
1. 新手Linux驱动开发者的五大生存法则作为一名在Linux驱动领域摸爬滚打多年的老司机,我见过太多新人刚入职时的迷茫和踩坑。驱动开发不同于应用层编程,它直接与硬件打交道,一个不小心就可能让整个系统崩溃。今天我就分享五个最实用的忠告&am…...
深入解析OpenPose:从原理到代码实现的完整指南
1. 姿态估计与OpenPose基础认知 想象一下你正在看一段街舞视频,舞者的每个关节运动轨迹都能被自动标注出来——这就是姿态估计技术的魅力。作为计算机视觉领域的经典任务,它的核心目标是检测图像或视频中的人体关键点(如肘部、膝盖等…...
MQTTX主题节点表功能:如何高效管理复杂MQTT主题结构
MQTTX主题节点表功能:如何高效管理复杂MQTT主题结构 【免费下载链接】MQTTX A Powerful and All-in-One MQTT 5.0 client toolbox for Desktop, CLI and WebSocket. 项目地址: https://gitcode.com/gh_mirrors/mq/MQTTX MQTTX是一款功能强大的跨平台MQTT 5.0…...
别再用鼠标拖滚动条了!GoLand 2022.2.3 这几个插件让你的代码阅读效率翻倍
GoLand 2022.2.3 插件组合:打造专业开发者的代码阅读工作流 作为一名长期与Go代码打交道的开发者,你是否经历过这样的场景:接手一个数万行代码的项目时,面对密密麻麻的函数和结构体,像在迷宫中寻找出口;或是…...
如何用GHelper替代Armoury Crate,让华硕笔记本性能与续航双丰收?
如何用GHelper替代Armoury Crate,让华硕笔记本性能与续航双丰收? 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus,…...
如何用ULTIMATE ANIMATION COLLECTION打造3A级游戏动画效果?Unity 2022实战案例解析
如何用ULTIMATE ANIMATION COLLECTION打造3A级游戏动画效果?Unity 2022实战案例解析 在游戏开发领域,动画质量往往是区分平庸作品与精品的关键分水岭。当玩家控制角色挥剑时剑刃的轨迹是否流畅自然,角色与环境互动时是否呈现真实的物理反馈&a…...
[技术解析] 差异图引导:破解无人机集群微小目标检测的“消失”难题
1. 无人机集群检测的痛点:为什么小目标会"消失"? 当你用无人机监控一片区域时,最头疼的莫过于屏幕上那些比蚂蚁还小的黑点——它们可能是入侵的无人机,也可能是需要追踪的野生动物。但传统算法处理这些目标时࿰…...
Anthropic 新政策与功能更新:AI 市场竞争下的博弈与挑战
Claude 新收费政策:第三方代理使用需额外付费上周末,Anthropic 告知订阅用户,若大量使用 Claude AI 模型驱动 OpenClaw 等第三方代理,需额外付费。月度订阅用户虽仍可通过第三方代理使用 Claude 模型,但需通过 Anthrop…...
2026行李箱推荐别乱买!唯尊、海澜之家、森马、外交官、珉璐保罗五款横评
对于技术从业者而言,行李箱不仅是装载衣物的容器,更是保护精密电子设备、应对高频差旅与跨城迁移的可靠装备。无论是前往异地调试系统、参加技术峰会,还是举家搬迁,一个设计合理、性能可靠的行李箱能显著提升出行效率与体验。本文…...
JPEGView:1MB实现效率革命的图像工具全指南
JPEGView:1MB实现效率革命的图像工具全指南 【免费下载链接】jpegview Fork of JPEGView by David Kleiner - fast and highly configurable viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimal GUI. Basic on-the-fly image proces…...
