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

【C++】拷贝构造函数,析构函数详解!

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、析构函数
    • 1.概念
    • 2.特点
    • 3.案例
  • 二、拷贝构造函数
    • 1.拷贝构造函数的引入
    • 2.格式
    • 2.概念
    • 3.特点
    • 4.解决引入问题
    • 5.总结

一、析构函数

1.概念

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由
编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
析构函数是用于在对象被删除之前的清理工作,它在对象生命周期即将结束时会被自动调用。(析构函数可以清理对象并且释放内存)

2.特点

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

  1. 析构函数名是在类名前加上字符 ~
  2. 无参数无返回值类型。
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
    函数不能重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
  5. 关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器
    生成的默认析构函数,对自定类型成员调用它的析构函数

3.案例

class Time
{
public:
~Time()
{
cout << "~Time()" << endl;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
private:
// 基本类型(内置类型)
int _year = 1970;
int _month = 1;
int _day = 1;
// 自定义类型
Time _t;
};
int main()
{
Date d;
return 0;
}

上述代码定义了两个类Data和Time。其中Data类中存在一个自定义类型变量Time,主方法中只创建了Data对象。那么在main方法中根本没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?

答:因为main方法中创建了Date对象d,而d中包含4个成员变量,其中_year, _month,_day三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;而_tTime类对象,所以在d销毁时,要将其内部包含的Time类的_t对象销毁,需要调用Time类的析构函数。但是main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器只会调用Date类的析构函 数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数,目的是在其内部 调用Time类的析构函数,即当Date对象销毁时,要保证其内部每个自定义对象都可以正确销毁 ,main函数中并没有直接调用Time类析构函数,而是显式调用编译器为Date类生成的默认析构函数
注意:创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数

二、拷贝构造函数

1.拷贝构造函数的引入

如下代码:
创建Stack类和Date类。

class Date
{
public:void print(){}
private:int _year =1;int _month =1;int _day =1;
};
class Stack
{public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}private:int* _array;size_t _size;size_t _capacity;
};

使用传值的方式进行调用。

void fun1(Date d)
{//...
}
void fun2(Stack s)
{//...
}

主函数

int main()
{Date d1(1999, 1, 1);fun1(d1);Stack s1;fun2(s1);return 0;
}

在这里插入图片描述

可以发现运行报错!!!为什么呢?

在C语言中我们遇到这种情况是没有问题的,但是在C++中,由于引进了析构函数,也就是说每次对象试用结束,系统都会自动调用析构函数进行对象的清除工作,正因如此我们在传值的时候,会再次创建一个对象复制过去,当结束函数调用时,会自动调用析构函数对当前对象进行清除,【如果对象中都是变量的话是没有问题的,因为值传递的改变不影响外部的变量,它只是一份拷贝。但是,如果对象中有指针类型的变量,它们指向的是同一位置,第一次函数调用结束后,析构函数已经对指向的位置进行了清除,第二次外部对象结束时,在调用析构函数,就会造成二次析构】。上面例子中Date类中全是普通变量,不会出现问题,造成二次析构。
为了解决上面的问题我们引入了拷贝构造函数。(通过深拷贝解决问题)

2.格式

类名(const 类名 &参数)

2.概念

只能有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存 在的类类型对象创建新对象时由编译器自动调用。

3.特点

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,
    因为会引发无穷递归调用。

例如:

class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{_year = year;_month = month;_day = day;
}
下面是拷贝构造!!
Date(const Date& ddd) // 正确写法
Date(const Date ddd) // 错误写法:编译报错,会引发无穷递归
{_year = d._year;_month = d._month;_day = d._day;
}
private:int _year;int _month;int _day;
};

主函数

int main()
{Date d1;Date d2(d1);return 0;
}
  • Date(const Date d) // 错误写法:编译报错,会引发无穷递归; 因为【Date d】参数会继续生成一个拷贝构造,如此往复循环。
  • *Date(const Date& ddd) // 正确写法 使用传引用就可以解决这个问题。因为ddd就是对象d1的一个别名,this指针指向d2,ddd传给了this,就相当于把d1给了d2,(传递指针也可以,但是很难用),规定必须使用引用。

4.解决引入问题

学到这里我们就可以很好地解决之前抛出的问题了。使用拷贝构造,将原来对象玩玩整整的拷贝一份出来,尤其是内部指针所指向的空间,拷贝时也会去开辟一块新的空间。这样在函数调用函数结束时,系统自动调用其析构造函数时,就不会造成一个地方多次析构了。各玩各的。

5.总结

内置类型系统会默认生成拷贝构造进行值拷贝,对自定义类型调用它的拷贝构造。
并不是所有的对象都需要拷贝构造:

  • 类中如果没有涉及资源申请时(例如 new申请空间),拷贝构造函数是否写都可以;
  • 一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
  • 拷贝构造也是构造,是拷贝构造的一个重载。

相关文章:

【C++】拷贝构造函数,析构函数详解!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

qml ParticleSystem3D使用介绍

在 Qt Quick 3D 中,ParticleSystem3D 是用来创建和控制3D粒子系统的元素。粒子系统是图形编程中用于模拟液体、烟雾、火、星空等现象的技术,它通过生成大量小粒子来模拟这些效果。ParticleSystem3D 提供了一个框架,允许开发者定义粒子的各种属性,如生命周期、速度、颜色、大…...

集团投融资大数据平台解决方案

一、项目背景 项目为集团型公司大数据平台项目&#xff0c;整个项目周期约为6个月&#xff0c;整体呈现了对外的数据大屏驾驶仓和对内的看板报表&#xff0c;减少了客户内部数据上报和报表制作的重复工作量&#xff0c;为集团数据决策奠定基础。 二、项目目标 战略层&#xff…...

深信服技术认证“SCSA-S”划重点:渗透测试工具使用

为帮助大家更加系统化的学习网络安全知识&#xff0c;尽快通过深信服安全服务认证工程师认证&#xff0c;深信服推出“SCSA-S认证备考秘笈”共十期内容&#xff0c;“考试重点”内容框架&#xff0c;帮助大家快速get重点知识~ 划重点来啦 深信服安全服务认证工程师&#xff08;…...

CCFCSP试题编号:201803-2试题名称:碰撞的小球

一、题目描述 二、思路 1.首先妾身分析这个题目&#xff0c;想要解题&#xff0c;得得解决2个问题。 1&#xff09;判断小球到达端点或碰撞然后改变方向&#xff1b; 2&#xff09;每时刻都要改变位置 两个问题都比较好解决&#xff0c;1&#xff09;只要简单判断坐标&…...

《安富莱嵌入式周报》第327期:Cortex-A7所有外设单片机玩法LL/HAL库全面上线,分享三款GUI, PX5 RTOS推出网络协议栈,小米Vela开源

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 1、2023 Hackaday大赛胸牌开源 Vectorscope-main.zip (66.83MB) GitHub - Hack-a-Day/Vectorscope: Vectorscope badg…...

面试官:【js多维数组扁平化去重并排序】

文章目录 前言方法一方法二方法三方法四总结后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;JavaScript &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&a…...

C#编程题分享(3)

n的阶乘问题 输⼊整数n&#xff0c;输出n的阶乘。 int n Convert.ToInt32(Console.ReadLine()); int jiecheng 1; for (int i 1; i < n 1; i) {jiecheng * i; // 1 * 2 * 3 * .....} Console.WriteLine("{0}的阶乘是&#xff1a;{1}", n, jiecheng); q^n次…...

Redis下载和安装(Windows系统)

通过 GitHub 来下载 Windows 版 Redis 安装包,下载地址&#xff1a;点击前往。 打开上述的下载链接&#xff0c;Redis 支持 32 位和 64 位的 Window 系统&#xff0c;大家根据个人情况自行下载&#xff0c;如图 1 所示&#xff1a; 下载完成后&#xff0c;打开相应的文件夹&a…...

MySQL数据库:开源且强大的关系型数据库管理系统

大家好&#xff0c;我是咕噜-凯撒&#xff0c;数据在当今信息化时代的重要性不可忽视。作为企业和组织的重要资产&#xff0c;数据的管理和存储变得至关重要&#xff0c;MySQL作为一种关系型数据库管理系统&#xff0c;具有非常多的优势&#xff0c;下面简单的探讨一下MySQL数据…...

如何在AD的PCB板做矩形槽孔以及如何倒圆弧角

Altium Designer 22下载安装教程-CSDN博客 如何在AD上创建完整的项目-CSDN博客 开始前&#xff0c;请先安装后AD&#xff0c;并创建好项目。 目录 1. 如何在AD的PCB板做矩形槽孔 2. 如何在AD的PCB板倒圆弧角 1. 如何在AD的PCB板做矩形槽孔 首先&#xff0c;我们进入上面创…...

SpringMVC日志追踪笔记整理

新建logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration><property name"PATH" value"./log/business"></property><appender name"STDOUT" class"ch.qos.logback…...

UML建模图文详解教程06——顺序图

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;《UML面向对象分析、建模与设计&#xff08;第2版&#xff09;》吕云翔&#xff0c;赵天宇 著 顺序图概述 顺序图(sequence diagram&#xff0c;也…...

睡前随笔记录

一个人从出生到长大&#xff0c;就像一部手机从新用到旧。手机里面积累了太多的缓存&#xff0c;积累了太多的照片&#xff0c;各种app的数据&#xff0c;安装了各式各样的程序。 所以大概这就是年纪越大&#xff0c;记性越差的原因吗&#xff1f;就像一个屋子&#xff0c;堆满…...

微服务学习|Feign:快速入门、自定义配置、性能优化、最佳实践

RestTemplate方式调用存在的问题 先来看我们以前利用RestTemplate发起远程调用的代码 存在下面的问题 代码可读性差&#xff0c;编程体验不统一 参数复杂URL难以维护 Feign的介绍 Feign是一个声明式的http客户端&#xff0c;官方地址: https://github.com/OpenFeign/feign …...

使用【画图】软件修改图片像素、比例和大小

打开电脑画图软件&#xff0c;点击开始 windows附件 画图 在画图软件里选择需要调整的照片&#xff0c;点击文件 打开 在弹出窗口中选择照片后点击打开 照片在画图软件中打开后&#xff0c;对照片进行调整。按图中顺序进行 确定后照片会根据设定的值自动调整 保存…...

DevOps 事后分析

众所周知&#xff0c;系统的变化会带来不稳定&#xff0c;进而引发事故。迁移到 DevOps 使世界各地的组织能够以更小的增量和更高的频率进行发布。这降低了特定版本中失败的风险。另一方面&#xff0c;增加发布数量并不一定会减少待命团队需要响应的事件数量。 事件响应团队的…...

fastdfs-client-java-1.30 maven 打包安装

1. 进入源代码目录&#xff0c;打开cmd mvn clean install 或者 mvn package 问题不大的话会在同级目录target目录下生成打包后文件 2. 当前目录下cmd进行maven安装 mvn install:install-file -DgroupIdorg.csource -DartifactIdfastdfs-client-java -Dversion${version} -D…...

【视觉SLAM十四讲学习笔记】第三讲——旋转矩阵

专栏系列文章如下&#xff1a; 【视觉SLAM十四讲学习笔记】第一讲——SLAM介绍 【视觉SLAM十四讲学习笔记】第二讲——初识SLAM 本章将介绍视觉SLAM的基本问题之一&#xff1a;如何描述刚体在三维空间中的运动&#xff1f; 旋转矩阵 点、向量和坐标系 三维空间由3个轴组成&…...

Linux驱动开发笔记(四):设备驱动介绍、熟悉杂项设备驱动和ubuntu开发杂项设备Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134533533 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…...

封海外是否可以阻断海外流量攻击

很多新人GM在租用服务器的时候&#xff0c;经常会问到机器是否可以封海外的问题&#xff0c;觉得流量攻击多数来自海外流量&#xff0c;就认为把海外封了就可以了&#xff0c;这样子海外流量就打不进来&#xff0c;就不用担心流量攻击了。实际上屏蔽海外是无法隔绝海外流量攻击…...

Pake:革命性的轻量级网页转桌面应用现代化解决方案

Pake&#xff1a;革命性的轻量级网页转桌面应用现代化解决方案 【免费下载链接】Pake &#x1f931;&#x1f3fb; Turn any webpage into a desktop app with one command. 项目地址: https://gitcode.com/GitHub_Trending/pa/Pake 在当今Web技术蓬勃发展的时代&#x…...

电路分析‘偷懒’神器:互易定理在求解复杂电阻网络时的实战技巧与避坑指南

电路分析‘偷懒’神器&#xff1a;互易定理在求解复杂电阻网络时的实战技巧与避坑指南 深夜的实验室里&#xff0c;老张盯着电路板上密密麻麻的电阻网络叹了口气。这个由47个电阻组成的测试电路&#xff0c;客户要求明天一早提交关键节点的电压分析报告。正当他准备熬夜列方程…...

高端化战略落地,爱芯元智如何撬动全球智驾市场?

2026年&#xff0c;智能汽车芯片的竞技场已经从“拼算力参数”全面转向“拼量产落地与商业生态”。在2026北京车展上&#xff0c;全球领先的AI推理系统级芯片&#xff08;SoC&#xff09;供应商爱芯元智&#xff08;0600.HK&#xff09;不仅正式宣告了智能汽车芯片产品线的高端…...

告别公网IP烦恼:用VS Code Tunnel免费搭建你的远程开发环境(保姆级教程)

告别公网IP烦恼&#xff1a;用VS Code Tunnel免费搭建你的远程开发环境&#xff08;保姆级教程&#xff09; 远程开发环境搭建一直是开发者面临的痛点之一。想象一下这样的场景&#xff1a;你在办公室的台式机上开始了一个项目&#xff0c;下班后需要继续在家里的笔记本上工作…...

Win11Debloat:三步轻松解决Windows 11臃肿问题,让你的电脑重获新生

Win11Debloat&#xff1a;三步轻松解决Windows 11臃肿问题&#xff0c;让你的电脑重获新生 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other chan…...

C/C++ 多线程的学习心得总结

个人觉得在学习多线程编程之前最好先了解进程和线程的关系, 然后在学习线程工作方式的过程中动手写个(我是从抄开始的)多线程的小程序, 会对学习多线程有很大的帮助, 否则只有理论是很抽象的.在学习多线程编程之前, 必须先知道什么是 线程函数, 线程函数就是另一个线程的入口函…...

3步解决音乐歌词获取难题:163MusicLyrics歌词提取工具实战指南

3步解决音乐歌词获取难题&#xff1a;163MusicLyrics歌词提取工具实战指南 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 还在为找不到心爱歌曲的歌词而烦恼吗&#xff…...

【论文阅读】Learning from Long-Term Engagement: Adaptive Tutoring Dialogue Planning for Personalized Educa

【论文阅读】Learning from Long-Term Engagement: Adaptive Tutoring Dialogue Planning for Personalized Education 摘要 scaffold 支架式教学 或 教学支架 例&#xff1a;The teacher provided scaffolds for the students. →老师为学生提供了学习支架&#xff08;教学辅助…...

如何用CheatEngine-DMA插件实现终极内存修改:5步完整指南

如何用CheatEngine-DMA插件实现终极内存修改&#xff1a;5步完整指南 【免费下载链接】CheatEngine-DMA Cheat Engine Plugin for DMA users 项目地址: https://gitcode.com/gh_mirrors/ch/CheatEngine-DMA 在游戏修改和内存分析领域&#xff0c;CheatEngine-DMA插件为D…...