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

c++的拷贝构造函数和赋值函数

拷贝构造函数和赋值函数

什么是拷贝构造

是一种特殊构造函数,如果没有显式的实现,编译器就会自动生成。

class 类名
{
public:// 拷贝构造类名(const 类名& that){}
};
什么时候会调用拷贝构造

当使用一个类对象给另一个新的类对象初始化时,就会自动调用拷贝构造。

#include <iostream>
using namespace std;
​
class Test
{
public:Test(void){   cout << "调用了普通的构造函数" << endl;}   Test(const Test& that){   cout << "调用了拷贝构造" << endl;}   
};
​
void func(Test t)
{
​
}
​
int main(int argc,const char* argv[])
{Test t1;        // 调用的是普通构造Test t2 = t1;   // 调用的是拷贝构造func(t1);       // 调用的是拷贝构造return 0;
}
拷贝构造的任务是什么

拷贝构造参数对象的所有成员变量挨个赋值给新对象的成员变量,一般情况下编译器自动生成的拷贝构造就能完全满足我们使用需求。

什么时候需要显式实现拷贝构造

当成员变量中有指针成员且指向了堆内存,就需要显式实现拷贝构造。

编译器自动生成的拷贝构造,只会对成员变量挨个赋值,如果成员变量中有指针变量且指向堆内存,结果就两个对象的指针变量同时指向一份堆内存,当它们执行析构函数时,会把这块堆内存释放两次,产生 double free or corruption 的错误。

正确的做法应该是先给新对象的指针变量重新申请一份堆内存,然后把旧对象的指针变量所指向的内存拷贝到新对象的指针变量所指向的内存。

#include <iostream>
using namespace std;
​
class Test
{int* ptr;
public:Test(int num){ptr = new int;cout << "new:" << ptr << endl;*ptr = num;}
​~Test(void){cout << "delete:" << ptr << endl;delete ptr;}
​/* 编译器生成的拷贝构造,会造成 double freeTest(const Test& that){ptr = that.ptr; }*/Test(const Test& that){// 给新对象的指针变量重新申请堆内存ptr = new int(*that.ptr);// 把旧对象的指针变量所指向的内存拷贝给新对象的指针变量所指向的内存,如果不方便解引用时可以使用memcpy函数}
​void show(void){cout << "val:" << *ptr << " addr:" << ptr << endl;}
};
​
int main(int argc,const char* argv[])
{Test t1(12345);Test t2 = t1;t1.show();t2.show();
​return 0;
}
什么是赋值函数

是一种特殊的成员函数,如果没有显式实现,编译器会自动生成。

class 类名
{
public:// 赋值函数const 类名& operator=(const 类名& that){}
};
什么时候会调用赋值函数

当一个旧对象给另一个旧对象赋值时会自动调用赋值函数。

当一个旧对象给另一个新对象初始化时会自动调用拷贝构造函数。

#include <iostream>
using namespace std;
​
class Test
{
public:Test(const Test& that){   cout << "调用了拷贝构造" << endl;}   
​void operator=(const Test& that){   cout << "调用了赋值函数" << endl;}   
};
​
int main(int argc,const char* argv[])
{Test t1;        // 调用了普通的构造函数Test t2 = t1;   // 调用了拷贝构造t1 = t2;        // 调用的是赋值函数return 0;
}
赋值函数的任务是什么

赋值函数与拷贝构造的任务几乎相同,都是挨个给成员变量赋值,但如果需要显式实现时,它的业务逻辑不同。

什么时候需要显式实现赋值函数

当需要显式实现拷贝构造时,就需要显式实现赋值函数,它们两个面临问题是一样的。

赋值函数不应该对成员指针变量赋值,而应该对象成员指针变量所指向的内存进行拷贝。

#include <iostream>
using namespace std;
​
class Test
{int* ptr;
public:Test(int num){ptr = new int;cout << "new " << ptr << endl;*ptr = num;}~Test(void){cout << "delete " << ptr << endl;// delete ptr;}
​Test(const Test& that){ptr = new int;// 如果不方便解引用,可以调用memcpy函数进行拷贝*ptr = *that.ptr;cout << "new " << ptr << "调用了拷贝构造" << endl;}
​const Test& operator=(const Test& that){// 当ptr和that.ptr指向的内存块大小一样,可以直接进行内存拷贝*ptr = *that.ptr;cout << "调用了赋值函数" << endl;return *this;/*当对象的ptr指向的内存与与that.ptr指向的内存块不一样大先释放旧的ptr再分配新的,要与that.ptr的内存块一样大然后再拷贝*/}
};
​
int main(int argc,const char* argv[])
{Test t1(1234);      // 调用了普通的构造函数Test t2 = t1;   // 调用了拷贝构造t1 = t2;        // 调用的是赋值函数return 0;
}
浅拷贝与深拷贝

拷贝就是一个对象给另一个对象赋值,编译器自动生成的拷贝构造和赋值函数执行的业务逻辑就是浅拷贝(成员指针给成员指针赋值),深拷贝就是把成员指针所指向的内存拷贝给另一个成员指针所指向的内存。

浅拷贝就是指针给指针赋值,深拷贝就内存给内存赋值。

注意:如果成员变量中没有成员指针,则浅拷贝就可以满足需求,如果如果成员变量中有成员指针且指向堆内存,则必须手动实现深拷贝,否则就会出现 double free or corruption 的错误。

相关文章:

c++的拷贝构造函数和赋值函数

拷贝构造函数和赋值函数 什么是拷贝构造 是一种特殊构造函数&#xff0c;如果没有显式的实现&#xff0c;编译器就会自动生成。 class 类名 { public:// 拷贝构造类名(const 类名& that){} }; 什么时候会调用拷贝构造 当使用一个类对象给另一个新的类对象初始化时&…...

什么自动猫砂盆才适合旅游党?4个选购技巧统统告诉你!

有没有能让我们防夹3天不在家都不用担心猫咪铲屎问题的方法&#xff1f;当然有了&#xff01;自动猫砂盆就是最好的选择&#xff0c;要知道&#xff0c;有个好用合适的自动猫砂盆在家的话&#xff0c;根本不用担心生虫发臭的问题出现&#xff0c;因为自动猫砂盆能及时感应到猫咪…...

算法知识点————双指针【删除重复元素】【反转链表】

删除重复元素 题目&#xff1a;//给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数 思路&#xff1a…...

建造者模式builder

此篇为学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/builder 能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象...

IEC103设备数据 转 IEC61850项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 配置VFBOX网关采集103设备数是 2 5 用IEC61850协议转发数据 4 6 网关使用多个逻辑设备和逻辑节点的方法 6 7 IEC103协议说明 8 8 案例总结 9 1 案例说明 设置网关采集IEC103设备数据把采集的数据转成IEC61850协议转发…...

438.找到字符串中所有字母异位词

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 很容易想到&#xff0c;这个题目要求我们在字符串s中找到一个定长的窗口让窗口里面出现异位词。 OK&#xff0c;先思考一下怎么快速判断两个字符串是否是异位词&#xff1f; 比较简单的方法是…...

Microsoft SC-100: Microsoft 网络安全架构师

SC-100认证介绍 Microsoft SC-100: Microsoft 网络安全架构师是微软网络安全方向的相关证书&#xff0c; 作为 Microsoft 网络安全架构师&#xff0c;你要将网络安全策略转化为保护组织的资产、业务和运营的功能。 你要设计、指导实现和维护遵循零信任原则和最佳做法的安全性解…...

代码随想录训练营day42|188.买卖股票的最佳时机IV,309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

188.买卖股票的最佳时机IV 变成了最多可以买卖k只股票 class Solution { public:int maxProfit(int k, vector<int>& prices) {vector<vector<int>> dp(prices.size(),vector<int>(2*k1,0));for(int i1;i<2*k1;i2){dp[0][i]-prices[0];}//初始…...

解决Pynput不能在Ubuntu22.04上正常使用问题

pynput 是一个 Python 库&#xff0c;它提供了一套简单的接口来控制和监控输入设备&#xff0c;包括鼠标和键盘。这个库允许开发者编写跨平台的代码来处理输入事件&#xff0c;无需担心底层操作系统的差异。 下面是pynput的测试程序&#xff1a; from pynput.keyboard import …...

IPV4端口数据有哪些?

关于IPv4的端口数据包括端口号&#xff0c;协议类型&#xff0c;端口状态&#xff0c;扫描时间以及开放时间&#xff0c;这些是常见的实时IPv4端口扫描和分析数据。 IPv4端口号 Ipv4端口号是一个16位的无符号整数&#xff0c;范围从0到65535&#xff0c;这些端口号用于区分运…...

【爱加密_云平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

Open CASCADE学习|按圆离散旋转体

旋转体是一个非常重要的概念&#xff0c;它涉及到三维空间中由二维曲线绕某一轴线旋转形成的立体形状。这种旋转体的形成过程&#xff0c;实际上是一个连续变化的动态过程&#xff0c;但在数学和几何学中&#xff0c;我们往往通过静态的方式来描述和研究它。 旋转体的基本特性…...

无人矿车使用ZMQ消息代理进行跨机互联进行消息收发

目录 背景 前景知识 1.启动一个代理服务器 2.发布者 3.订阅者 实际应用 1.模拟智驾收来自交互箱131的按钮json数据 2.模拟交互箱131收来自智驾137的cjson数据 背景 在调试防爆无轨无人矿车时&#xff0c;出现消息代理不能很好转发&#xff0c;于是在公司通过代理的方式…...

医疗机构关于DIP/DRG信息化建设

推进DIP/DRG支付方式改革是一项系统性工程&#xff0c;牵一发而动全身。作为河北省DIP试点医院&#xff0c;河北医科大学第二医院将信息化与创新性管理理念融合&#xff0c;用好支付工具做好精细化管理&#xff0c;积极应对改革。 ■ 改革背景 国家医疗保障局制定的《DRG/DIP支…...

100个候选人,没一个能讲明白什么是自动化框架?

什么是自动化测试框架 01 什么是框架 框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及构件实例间交互的方法。它规定了应用的体系结构&#xff0c;阐明了整个设计、协作构件之间的依赖关系、责任分配和控制流程&#xff0c;表现为一组抽象类以及其实例之间…...

数据结构与算法1: 链表

题目名称&#xff1a; 重排链表 链接&#xff1a; ​​​​​​. - 力扣&#xff08;LeetCode&#xff09; 介绍&#xff1a;本题的目标是将链表进行重新组合&#xff0c;如下图。 如果按照标准的解法&#xff0c;我们需要实现三步 1. 链表中点的获取 2. 链表的反转 3. 链…...

【专题】2024年8月医药行业报告合集汇总PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37621 在科技飞速发展的当今时代&#xff0c;医药行业作为关乎人类生命健康的重要领域&#xff0c;正处于前所未有的变革浪潮之中。数智医疗服务的崛起&#xff0c;为医疗模式带来了全新的转变&#xff0c;开启了医疗服务的新时代。…...

这10种人不适合干项目经理,你在其中吗?

在一个项目中&#xff0c;项目经理扮演着至关重要的角色&#xff0c;他们需要协调各种资源、管理团队、制定计划以及应对各种挑战。然而&#xff0c;并非每个人都适合担任项目经理的角色。以下他们天生不适合当项目经理&#xff0c;你会在其中找到自己的类型吗&#xff1f; 1、…...

IT每日英语(三)

系列文章目录 IT每日英语&#xff08;二&#xff09; 文章目录 系列文章目录前言1.collie2.century3.farewell4.meme5.hall6.needle7.simulate8.emulate9.arbitray10.laboratory11.jest12.suite13.approach14.satellite15.instance16.representation 前言 这里给出的是本人在…...

【保姆级教程】如何创建一个vitepress项目?

文章目录 安装前的准备工作项目安装创建文件初始化文件安装依赖遇到了 missing peer deps 警告&#xff1f;命令行设置向导 完成 安装前的准备工作 Node.js 18 及以上版本。通过命令行界面 (CLI) 访问 VitePress 的终端。支持 Markdown 语法的编辑器。推荐 VSCode 及其官方 Vu…...

OpenClaw终极指南:GLM-4.7-Flash从入门到精通

OpenClaw终极指南&#xff1a;GLM-4.7-Flash从入门到精通 1. 为什么选择OpenClawGLM-4.7-Flash组合 去年冬天&#xff0c;当我第一次尝试用Python脚本自动化处理日报时&#xff0c;发现传统脚本在面对动态网页和复杂文档时显得力不从心。直到遇见OpenClaw这个能像人类一样操作…...

Chandra OCR真实测评:对比GPT-4o,开源OCR模型表现如何

Chandra OCR真实测评&#xff1a;对比GPT-4o&#xff0c;开源OCR模型表现如何 最近在整理一堆扫描版的实验报告和学术论文&#xff0c;里面混杂着复杂的表格、手写注释和数学公式&#xff0c;真是让人头疼。传统的OCR工具&#xff0c;比如Tesseract&#xff0c;处理这种文档就…...

GHelper深度解析:华硕笔记本终极性能调校实战指南

GHelper深度解析&#xff1a;华硕笔记本终极性能调校实战指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: h…...

Linux网络开发实战:如何用MDIO总线扫描PHY设备并注册驱动(附完整代码解析)

Linux网络开发实战&#xff1a;MDIO总线扫描PHY设备与驱动注册全解析 在嵌入式Linux网络设备开发中&#xff0c;PHY芯片作为物理层接口的核心组件&#xff0c;其驱动加载和设备管理机制直接影响网络功能的稳定性。MDIO总线作为连接MAC控制器与PHY芯片的标准接口&#xff0c;其扫…...

OpenClaw跨平台对比:nanobot在Mac/Win/Linux的表现差异

OpenClaw跨平台对比&#xff1a;nanobot在Mac/Win/Linux的表现差异 1. 测试背景与实验设计 去年夏天我开始尝试用OpenClaw搭建个人自动化工作流时&#xff0c;发现不同操作系统下的表现差异远超预期。这次我选择了基于Qwen3-4B模型的nanobot镜像&#xff0c;在MacBook Pro M1…...

HRN模型与PID控制结合:实时面部动画调节系统

HRN模型与PID控制结合&#xff1a;实时面部动画调节系统 1. 引言 想象一下&#xff0c;你正在制作一部动画电影&#xff0c;主角的面部表情需要精确到每一帧的微妙变化。传统的手工调整方式耗时耗力&#xff0c;而自动生成的表情又往往缺乏自然流畅的过渡。这就是为什么我们需…...

24小时运行OpenClaw:nanobot镜像监控网站变更并邮件报警

24小时运行OpenClaw&#xff1a;nanobot镜像监控网站变更并邮件报警 1. 为什么需要自动化网站监控 上周我负责的一个项目突然出了状况——客户官网的产品价格页面被意外修改&#xff0c;导致大量用户投诉。团队花了整整两天才发现问题根源。这件事让我意识到&#xff0c;对于…...

如何高效管理《神界:原罪2》模组?Divinity Mod Manager终极指南

如何高效管理《神界&#xff1a;原罪2》模组&#xff1f;Divinity Mod Manager终极指南 【免费下载链接】DivinityModManager A mod manager for Divinity: Original Sin - Definitive Edition. 项目地址: https://gitcode.com/gh_mirrors/di/DivinityModManager Divini…...

从理论到实践:双有源桥DAB-SPS控制模式仿真全解析

1. 双有源桥DAB与SPS控制模式入门 第一次接触双有源桥&#xff08;Dual Active Bridge&#xff0c;简称DAB&#xff09;时&#xff0c;我被它优雅的对称结构吸引住了。这种DC-DC变换器拓扑就像一座精心设计的桥梁&#xff0c;两侧各有一个全桥电路&#xff0c;通过高频变压器耦…...

颠覆传统体验!5步打造完美魔兽争霸3环境:WarcraftHelper全方位优化指南

颠覆传统体验&#xff01;5步打造完美魔兽争霸3环境&#xff1a;WarcraftHelper全方位优化指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 经典游…...