详解拷贝构造

拷贝构造的功能

写法:

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

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

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

概念

浅拷贝:

深拷贝

小结


拷贝构造的功能

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

写法:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Mybatis框架的私人影院预约系统(附源码,包含数据库文件)

基于SpringBootMybatis框架的私人影院预约系统&#xff0c;附源码&#xff0c;包含数据库文件。 非常完整的一个项目&#xff0c;希望能对大家有帮助哈。 本系统的完整源码以及数据库文件都在文章结尾处&#xff0c;大家自行获取即可。 项目简介 该项目设计了基于SpringBoo…

软考126-上午题-【软件工程】-测试方法

一、测试方法 在软件测试过程中&#xff0c;应该为定义软件测试模板&#xff0c;即将特定的测试方法和测试用例设计放在一系列的测试步骤中。 软件测试方法分为&#xff1a;静态测试和动态测试。 1-1、静态测试。 静态测试是指被测试程序不在机器上运行&#xff0c;而是采用…

事务隔离级别的无锁实现方式 -- MVCC

MVCC的全称是Multiversion Concurrency Control(多版本并发控制器)&#xff0c;是一种事务隔离级别的无锁的实现方式&#xff0c;用于提高事务的并发性能&#xff0c;即事务隔离级别的一种底层实现方式。 在了解MVCC之前&#xff0c;我们先来回顾一些简单的知识点&#xff1a;…

最优算法100例之47-从尾到头打印单链表

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 从尾到头打印单链表 题解报告 方法1:头插法逆置单链表然后依次打印;注意此处是不带头结点的单链表,带头节点的操作稍微有…

网络篇09 | 运输层 udp

网络篇09 | 运输层 udp 01 简介UDP 是面向报文的 02 报文协议 01 简介 UDP 只在 IP 的数据报服务之上增加了一些功能&#xff1a;复用和分用、差错检测 UDP 的主要特点&#xff1a;无连接。发送数据之前不需要建立连接。 使用尽最大努力交付。即不保证可靠交付。 面向报文。…

【信号处理】心电信号传统R波检测定位典型方法实现(matlab)

关于 心电信号中QRS波检测是一个非常重要的步骤&#xff0c;可以用于实现重要波群的基本定位&#xff0c;在定位基础上&#xff0c;可以进一步分析心电信号的特征变化&#xff0c;从而为医疗诊断提供必要的参考。 工具 MATLAB ECG心电信号 方法实现 ECG心电信号加载 ecg …

基于深度学习的花卉检测系统(含PyQt界面)

基于深度学习的花卉检测系统&#xff08;含PyQt界面&#xff09; 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于swin_transformer深度学习网络模型的花卉检测系统&#xff0c;…

架构师系列-搜索引擎ElasticSearch(八)- 集群管理故障恢复

故障转移 集群的master节点会监控集群中的节点状态&#xff0c;如果发现有节点宕机&#xff0c;会立即将宕机节点的分片数据迁移到其它节点&#xff0c;确保数据安全&#xff0c;这个叫做故障转移。 下图中node1是主节点&#xff0c;其他两个节点是从节点 节点故障 此时node1…

【uniapp】vscode安装插件、ts校验、允许json文件注释

1、vscode安装的插件&#xff1a; uni-create-viewuni-hlperuniapp小程序扩展 2、ts校验 安装插件&#xff1a; pnpm i -D types/wechat-miniprogram uni-helper/uni-app-types配置tsconfig.json {"extends": "vue/tsconfig/tsconfig.json","compi…

论文笔记:The Expressive Power of Transformers with Chain of Thought

ICLR 2024 reviewer 评分 6888【但是chair 很不喜欢】 1 intro 之前的研究表明&#xff0c;即使是具有理想参数的标准Transformer&#xff0c;也无法完美解决许多大规模的顺序推理问题&#xff0c;如模拟有限状态机、判断图中的节点是否相连&#xff0c;或解决矩阵等式问题 这…

IOS 短信拦截插件

在使⽤iOS设备的时候, 我们经常会收到1069、1065开头的垃圾短信, 如果开了iMessage会更严重, 各种乱七⼋糟的垃圾信息会时不时地收到。 从iOS11开始, ⼿机可以⽀持恶短信拦截插件了. 我们可以通过该插件添加⼀些规则通过滤这些不需要的信息. ⼀. 使⽤xcode新建⼀个项⽬ 【1】…

MongoDB 初识

介绍 MongoDB是一种开源的文档型数据库管理系统&#xff0c;它使用类似于JSON的BSON格式&#xff08;Binary JSON&#xff09;来存储数据。与传统关系型数据库不同&#xff0c;MongoDB不使用表和行的结构&#xff0c;而是采用集合&#xff08;Collection&#xff09;(Mysql表)和…

LabVIEW直流稳定电源自动化校准系统

LabVIEW直流稳定电源自动化校准系统 直流稳定电源正向着智能化、高精度、多通道、宽量程的方向发展。基于LabVIEW开发环境&#xff0c;设计并实现了一种直流稳定电源自动化校准系统&#xff0c;以提升校准过程的整体效能&#xff0c;实现自动化设备替代人工进行电源校准工作。…

【DNS】

文章目录 DNS域名解析系统&#xff08;Domain Name System&#xff09;DNS系统需要解决的问题DNS域名解析系统&#xff08;Domain Name System&#xff09;问题1&#xff1a;DNS名字空间(The DNS Name Space&#xff09;DNS名字空间(The DNS Name Space)DNS名字空间(The DNS Na…

oracle 19c 主备 补丁升级19.22

补丁升级流程 备库升级 备库备份$ORALCE_HOME du -sh $ORACLE_HOME ​​​​​​​ 备份目录将dbhome_1压缩 cd $ORACLE_HOME cd .. Ls tar -cvzf db_home.tar.gz db_home_1 /opt/oracle/product/19c ​​​​​​​​​​​​​​ 关闭监听关闭数据库查看sq…

基于表面势的增强型p-GaN HEMT器件模型

来源&#xff1a;电子学报 22年 摘要 为了满足功率电路及系统设计对p-GaN HEMT&#xff08;High Electron Mobility Transistor&#xff09;器件模型的需求&#xff0c;本文建立了一套基于表面势计算方法的增强型p-GaN HEMT器件SPICE&#xff08;Simulation Program with Int…

【opencv】示例-travelsalesman.cpp 使用模拟退火算法求解旅行商问题

// 载入 OpenCV 的核心头文件 #include <opencv2/core.hpp> // 载入 OpenCV 的图像处理头文件 #include <opencv2/imgproc.hpp> // 载入 OpenCV 的高层GUI(图形用户界面)头文件 #include <opencv2/highgui.hpp> // 载入 OpenCV 的机器学习模块头文件 #includ…

数据库:SQL分类之DQL详解

1.DQL语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数 基本查询 条件查询&#xff08;where&#xff09; 聚合函数&#xff08;count、max、min、avg、sum &#xff09; 分组查询&…

Linux网络基础 (二) ——(IP、MAC、端口号、TCPUDP协议、网络字节序)

文章目录 IP 地址基本概念源IP地址 & 目的IP地址 MAC 地址基本概念源MAC地址 & 目的MAC地址 端口号基本概念源端口号 & 目的端口号 TCP & UDP 协议基本概念TCP 与 UDP 的抉择 网络字节序大端、小端字节序 &#x1f396; 博主的CSDN主页&#xff1a;Ryan.Alask…

OLTP 与 OLAP 系统说明对比和大数据经典架构 Lambda 和 Kappa 说明对比——解读大数据架构(五)

文章目录 前言OLTP 和 OLAPSMP 和 MPPlambda 架构Kappa 架构 前言 本文我们将研究不同类型的大数据架构设计&#xff0c;将讨论 OLTP 和 OLAP 的系统设计&#xff0c;以及有效处理数据的策略包括 SMP 和 MPP 等概念。然后我们将了解经典的 Lambda 架构和 Kappa 架构。 OLTP …