详解拷贝构造

news2024/11/17 23:46:23

拷贝构造的功能

写法:

拷贝构造函数的参数为什么是引用类型

系统自动生成的拷贝构造函数

拷贝构造的深拷贝与浅拷贝

概念

浅拷贝:

深拷贝

小结


拷贝构造的功能

拷贝构造函数可以把曾经实例化好的对象的数据拷贝给新创建的数据 ,可见说拷贝构造函数在功能上是构造函数的另一种形式。都是让对象初始化。

写法:

拷贝构造函数在语法层是构造函数的重载,函数名就是类名,无返回值,参数是该类类型对象的引用(为了保护被引用对象数据不被破坏,会在类型前面加上const)

 Date(const Date& d) //以日期类为例,定义拷贝构造的写法
Date d1;
 Date d2(d1); //以日期类为例,实例化对象时的写法

拷贝构造函数的参数为什么是引用类型

下面是定义的日期类的拷贝构造函数,但参数并不是引用类型

Date(const Date d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

因为是传值,实例化对象时需要调用拷贝构造函数把数据拷贝过来,但拷贝数据函数的参数又需要掉用拷贝构造函数,如此就死循环了,拷贝构造函数会被无限调用。如图所示这种情况编译器会强制报错

系统自动生成的拷贝构造函数

若未显式定义,编译器会生成默认的拷贝构造函数 默认的拷贝构造函数对象按内存存储 按字节序 完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝
下面代码中定义了一个时间类 Time ,又定义了一个日期类 Date , 时间类在日期类里实例化了对象_t,_t就是日期类的自定义类型,但并没有定义日期类的拷贝构造函数。那么系统自动生成的拷贝构造函数会怎么处理自定义类型_t和内置类型的年月日呢?
class Time {   //时间类
public:

Time() 
   {
_hour = 1;
_minute = 1;
_second = 1;
}

Time(const Time& t) //自定义时间类的拷贝构造函数
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}

private:

int _hour;
int _minute;
int _second;
};

class Date  //日期类,但没有自定义拷贝构造函数
{
	
private:
// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;

// 自定义类型
Time _t;  //时间类实例化对象 _t
	
};

int main(){

Date d1;
Date d2(d1); //拷贝对象d1的数据

 // 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数
    // 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数

return 0;
}



只需明晰一点即可,系统自动生成的默认拷贝构造对内置类型进行浅拷贝对自定义类型,会调用自定义类型的拷贝构造函数,若自定义类型并未定义拷贝构造函数,系统便会自动生成。

下图是代码执行示意图

下图是逻辑示意图

拷贝构造的深拷贝与浅拷贝

概念

浅拷贝:

又称值拷贝,是按字节序拷贝的,通俗的讲别的数据长啥样就拷贝啥样。

浅拷贝的细节:下面代码中还是定义了一个日期类,但增加了一个int*的变量它指向一块空间。这是让默认构造函数进行浅拷贝会发生什么呢?

class Date //日期类,并没有定义拷贝构造函数
{
public:

	Date()//构造函数
	{
		_year = 1;
		_month = 1;
		_day = 1;
			_a = (int*)malloc(sizeof(int) * 7); //开辟空间并把空间的值初始化
			for (int i = 0; i < 7; i++)
			{
				_a[i] = 0;
			}
	}

private:
	int _year;
	int _month;
	int _day;
	int* _a; //指向一块空间
};
int main()
{
	Date d; 
	Date d1(d); //拷贝d的值
}

结果:d对象和d1对象的数据会一模一样,如下图

我们发现d对象的值和d1对象的值一模一样,并且d对象中的_a和d1对象中的_a都指向同一块空间。如下图

上述就值浅拷贝的坏处,d1对象的_a并没有申请资源而是直接指向了d对象_a的空间,如果想让d1

_a也申请空间就需要深拷贝,想要深拷贝就需要自己定义一个拷贝构造函数,该拷贝构造函数如何申请空间要根据不同的场景具体实现。

深拷贝

下面的代码是对上面代码的改造,

class Date
{
public:

	Date() //构造函数
	{
		_year = 1;
		_month = 1;
		_day = 1;
			_a = (int*)malloc(sizeof(int) * 7);
			for (int i = 0; i < 7; i++)
			{
				_a[i] = 0;
			}
	}

	Date(const Date& d) //拷贝构造函数
	{
		_year = d._year; 
		_month = d._month;
		_day = d._day;

		_a = (int*)malloc(sizeof(int) * (sizeof(d._a) / sizeof(d._a[0])));  //开辟空间

			for (int i = 0; i < (sizeof(d._a) / sizeof(d._a[0])); i++)  //赋值
			{
				_a[i] = d._a[i];
			}
	}

private:
	int _year;
	int _month;
	int _day;
	int* _a;
};
int main()
{
	Date d;
	Date d1(d);
}

d1对象的_a会独自开空间并且拷贝d对象的数据,如下图这样就完成了拷贝构造的深拷贝了。

小结

拷贝构造是构造函数的重载。参数是该类类型的引用(一般会加上const),不加引用在逻辑是会让拷贝函数无限调用,此时编译器会报错。如果未显示定义拷贝构造函数,编译器会生成默认的拷贝构造函数默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。浅拷贝又称值拷贝,是按字节序拷贝的,通俗的讲别的数据长啥样就拷贝啥样。而深拷贝会申请资源(空间)再赋值。

另外我还为大家准备了几篇不错的博客

构造函数:  http://t.csdnimg.cn/MdHiA

希尔排序:   http://t.csdnimg.cn/uxSBG

堆排序的时间复杂度:  http://t.csdnimg.cn/OJLzI

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

书生·浦语大模型-第五节课笔记/作业

笔记 作业 原7b模型问题耗时: 4.5s lmdeploy推理耗时: 0.43s 不知道是否因为没有正确的输出 lmdeploy kv-cache推理耗时&#xff1a;2.9s 推理时新增 past_key_values 参数&#xff0c;该参数就会以追加方式保存每一轮的K V值。kvcache变量内容为((k,v), (k,v), …, (k,v))…

Node.js 中的 RSA 加密、解密、签名与验证详解

引言 在现代的网络通信中&#xff0c;数据安全显得尤为重要。RSA加密算法因其非对称的特性&#xff0c;广泛应用于数据的加密、解密、签名和验证等安全领域。本文将详细介绍RSA算法的基本原理&#xff0c;并结合Node.js环境&#xff0c;展示如何使用内置的crypto模块和第三方库…

【python】python抓取古诗文内容保存(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

下载了恶意软件怎么办,用这个软件可以解决 Mac电脑卸载软件 MacBook查杀病毒

随着苹果电脑在全球市场的普及&#xff0c;它们也日益成为恶意软件制作者的目标。这种趋势打破了许多人认为Mac系统不易受到病毒或恶意软件影响的传统观念。事实上&#xff0c;苹果电脑面临的恶意软件和安全威胁正在不断增多&#xff0c;这要求用户采取更加积极的措施来保护自己…

activiti初次学习

源代码地址&#xff1a;https://gitee.com/ZSXYX/activiti.git​ 1、安装插件 首先安装下图所示activiti,不确定是哪个插件有用的&#xff0c;有时间可排除下 在resources下创建一个文件夹&#xff1a;processes,右键&#xff0c;新建 生成&#xff1a; 选中act.bpmn20.xm…

TCHouse-C

一.概括 1.地域&#xff08;Region&#xff09; 地域&#xff08;Region&#xff09;指腾讯云数据仓库 TCHouse-C 物理服务器所在的地理区域。腾讯云不同地域之间网络完全隔离&#xff0c;购买后不能更换。&#xff08;地域一旦选定&#xff0c;购买后无法更改。&#xff09;…

L3 【哈工大_操作系统】操作系统启动

本节要点&#xff1a; 1、理解 OS 启动过程发生了什么&#xff0c;理解 OS 与 硬件 与 应用 之间的关系 2、本节讲解了 setup 模块 和 system 模块实现的功能 1、计算机上电时&#xff0c;操作系统在硬盘&#xff08;磁盘&#xff09;上&#xff0c;为了“取指执行”&#xff0…

IO流基本流

目录 什么是IO流 IO流的体系 字节流 FileOutputStream FileInputStream 字符集 字符流 FileReader FileWriter 字节流和字符流的使用场景 什么是IO流 内存不能永久化存储,程序停止,数据丢失,所以要添加一个存档功能,存储到硬盘的文件,我们要知道文件在哪里和如何传…

Jmeter配置服务器监控插件

1.安装插件管理器 插件官网地址&#xff1a;JMeter Plugins :: JMeter-Plugins.org 点击 Plugins Manager,如上图所示&#xff0c; &#xff0c;点击jar file下载“plugins-manager.jar”&#xff0c;下载后放到“jmeter\lib\ext”目录下&#xff0c;重启jmeter。 2.安装资源…

静电场中的导体与介质

静电场可能分布于填充了各种媒质的区域。虽然媒质宏观上保持电中性&#xff0c;但其内部的各种微观带电系统不可避免地会与静电场相互作用。 一般而言&#xff0c;媒质可分为三类&#xff1a;导体、介质(绝缘体)和半导体。在静电场中半导体特性与导体类似&#xff0c;因此仅就…

C# Window form 自定义控件的结构和设计(三)

C# Window form 自定义控件的结构和设计(三) 一、前面介绍了如何来创建第一个自定义的控件&#xff0c;以及一个测试程序。下面我们来看下如何在自定义控件中添加属性。 C#和其他.NET语言支持属性作为语言的第一类成员。把属性作为语言的基础属性有两点主要的有点&#xff1a…

Node.js 并发控制

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它使得 JavaScript 可以脱离浏览器在服务器端运行。由于 Node.js 采用单线程异步非阻塞 I/O 模型&#xff0c;它的并发处理能力也是非常强大的。本文将详细介绍 Node.js 的并发原理、概念、图解、解决方案…

洛谷-P2089 烤鸡

P2089 烤鸡 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N30; //const int M1e3*310; const int Mpow(3,10); int n; int arr[N]; //存临时方案 int res; //存方案数 int ans[M][N]; //存所有方案//x表示当前到…

k8s:kubectl 命令设置简写启用自动补全功能

k8s&#xff1a;kubectl 命令设置简写&启用自动补全功能 1、设置kubectl命令简写2、启用kubectl自动补全功能 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Kubernetes&#xff08;K8s&#xff09;是一个强大的容器编排平台&#xff0…

LangChain安装

安装步骤 1 安装Python环境 这里不介绍Python环境的配置&#xff0c;默认大家是已经安装并配置好Python运行环境的。 2 安装LangChain bash 复制代码 pip install langchain执行以上命令安装LangChain会默认安装LangChain的最新版本 3 测试安装结果 3.1 打印langchain版本…

如何获得easyrecovery软件密钥?2024最新学习步骤教程

如何获得easy recovery密钥&#xff1f;EasyRecovery是一款老牌的数据恢复软件&#xff0c;如果需要使用它来恢复数据&#xff0c;则需要购买密钥激活。然而&#xff0c;如果您只需要使用它一两次而不想花钱购买密钥&#xff0c;那么您可以使用免费的EasyRecovery密钥。请注意&…

贝乐虎儿歌v6.8.0解锁高级版亲子学习儿歌

软件介绍 贝乐虎儿歌免费版app&#xff0c;出自乐擎网络的创意工坊&#xff0c;专为孩子们雕琢了一系列富含创意的动画儿歌内容。这款app通过贝乐虎兄弟的可爱形象&#xff0c;让孩子们在愉快的观看中接触到各种儿歌和故事。不仅如此&#xff0c;app还巧妙地将古诗、英语等学习…

Java代码基础算法练习-求奇数和-2024.04.14

任务描述&#xff1a; 输入n个整数&#xff08;n从键盘输入&#xff0c;n>0&#xff0c;整数取值范围&#xff1a;0~1000&#xff09;&#xff0c;输出它们的奇数和。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;// 输入n个…

【Leetcode】1702. 修改后的最大二进制字符串

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个二进制字符串 b i n a r y binary binary &#xff0c;它仅有 0 0 0 或者 1 1 1 组成。你可以使用下面的操作任意次对它进行修改&#xff1a; 操作 1 &#xff1a;如果…

Nacos 入门篇---服务端如何处理客户端的服务注册请求?(三)

一、引言 ok呀&#xff0c;上个章节我们讲了Nacos客户端的服务自动注册&#xff0c;今天我们来看看服务端接收到了客户端的服务注册请求&#xff0c;服务端都做了哪些事情&#xff5e; 二、目录 目录 一、引言 二、目录 三、回顾上节内容&#xff1a; 四、Nacos 服务代码入…