C++:深拷贝和浅拷贝——拷贝构造、赋值构造必须自定义

news2024/9/21 17:57:13

https://www.bilibili.com/video/BV1qT4y1X7cQ/?spm_id_from=333.337.search-card.all.click&vd_source=d33b44674c517c8b7928e8d3ac316b37

1、赋值运算符重载

浅拷贝的错误代码:

class Distance
{
public:
	int* dis = NULL;
	Distance(int a)
	{
		dis = new int(a);
	}

	~Distance()
	{
		if (dis != NULL)
		{
			cout << "~distance" << endl;
			delete dis;
			dis = NULL;
		}
	}
};


int main()
{
	Distance p(23);
	Distance p2(24);
	p2 = p; //赋值构造
	
	return 0;
}  

在这里插入图片描述
C++默认提供给我们的赋值运算符函数,是浅拷贝。默认operator=是浅拷贝.
默认operator=是浅拷贝.默认operator=是浅拷贝.默认operator=是浅拷贝.默认operator=是浅拷贝.

由于是默认的系统提供的赋值函数;所以p2和p指向的是同一块内存;而析构的时候,p1先析构了堆内存;然后p2再去释放的时候,导致释放失败。
同时p2原先指向的堆内存并未正确释放,导致内存泄露。

定义自定义的赋值构造函数:

class Distance
{
public:
	int* dis = NULL;
	Distance(int a)
	{
		dis = new int(a);
	}

	Distance& operator = (const Distance& other)
	{
		if (dis != NULL)
		{
			delete dis;
			dis = NULL;
		}

		dis = new int(*other.dis);
		return *this;
	}

	~Distance()
	{
		if (dis != NULL)
		{
			delete dis;
			dis = NULL;
		}
	}
};

int main()
{
	Distance p(23);
	Distance p2(24);
	p2 = p;
	return 0;
}  

这样为啥不会出错了呢?因为p和p2分别指向自己的一块独立的内存,所以各自释放自己的内存不会失败;而如果是两个指针同时指向一块内存,那如果释放了多次,则会出错。

当类对象作为参数传递的时候,调用的是拷贝构造函数,所以这里也会有拷贝:

class Distance
{
public:
	int* dis;
	Distance(int a)
	{
		dis = new int(a);
	}

	~Distance()
	{
		if (dis != NULL)
		{
			cout << "~distance" << endl;
			delete dis;
			dis = NULL;
		}
	}
};

void func(Distance a)  //这里调用的是拷贝构造函数
{
	cout << *a.dis << endl;
}

int main()
{
	Distance p(23);
	func(p);
	return 0;
}

2、拷贝构造函数

错误1:

class Distance
{
public:
	int* dis = NULL;
	Distance(int a)
	{
		dis = new int(a);
	}

	~Distance()
	{
		if (dis != NULL)
		{
			delete dis;
			dis = NULL;
		}
	}
};

int main()
{
	Distance p(23);
	Distance p2(p); //拷贝构造, Distance p2 = p;这个也是调用拷贝构造,而不是赋值构造;

	return 0;
}  

由于C++默认提供的拷贝构造也是浅拷贝,导致俩指针指向同一个内存,所以释放多次导致错误。
Distance p2§; //拷贝构造, Distance p2 = p;这个也是调用拷贝构造,而不是赋值构造;

正确做法:

class Distance
{
public:
	int* dis = NULL;
	Distance(int a)
	{
		dis = new int(a);
	}

	Distance(const Distance& other)
	{
		cout << "copy constructor" << endl;
		if (dis != NULL)
		{
			delete dis;
		}
		dis = NULL;
		this->dis = new int(*other.dis);
	}

	~Distance()
	{
		if (dis != NULL)
		{
			delete dis;
			dis = NULL;
		}
	}
};

int main()
{
	Distance p(23);
	Distance p2 = p;

	return 0;
}  

总结:带有指针的成员,需要自定义拷贝构造、赋值构造函数,使得每个对象都有自己独立的内存空间,防止内存释放报错。

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

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

相关文章

轻量级xshell+manager远程监控jvisualvm

一、服务器端&#xff08;Linux&#xff0c;最小安装模式&#xff0c;没有图形界面&#xff09; 1.安装xauth 如果在Xshell中配置了X11转发后&#xff0c;出现如下提示&#xff1a; WARNING! The remote SSH server rejected X11 forwarding request. 则需要查看/etc/ssh/s…

esxi 6.7下安装openwrt(iStoreOS)网卡直通

esxi 6.7下安装openwrt&#xff08;iStoreOS&#xff09;网卡直通 esxi上创建一个iStoreOS系统的虚拟机&#xff0c;当主路由使用&#xff0c;网卡直通方式 1、工具 硬件&#xff1a; 工控机&#xff1a;装有esxi6.7系统&#xff08;192.168.100.2&#xff09;&#xff0c;配…

图像仿射变换与双线性插值

图像变换 下面的所有变换假设都是针对一幅图像&#xff0c;即一个三维数组&#xff08;HWC&#xff09;&#xff0c;这里为简单起见&#xff0c;假设图像都是单通道&#xff08;C1&#xff09;的。 (x,y)(x,y)(x,y): 原图像中某一点 A 的位置(x′,y′)(x′,y′)(x′,y′): 变换…

记一次系统重装后电脑的优化设置

总目录 文章目录总目录前言一、Windows设置1.系统2.应用3.隐私4.更新与安全二、系统使用偏好设置1.设置远程协助2.文件资源管理器偏好设置3.用户账户控制设置4.修改桌面文件的路径5.根据需求删除系统自带的无用的软件总结前言 由于之前总是电脑用着用着C盘不是满了&#xff0c…

Spring框架(九):Spring注解开发Annotation

Spring注解开发引子如何用注解替代xml基础配置Bean可以加一些注解来实现原有的xml文件的功能Component注解及其衍生注解依赖注入AutowireSpring非自定义的注解开发Spring其他注解注解的原理解析-xml方式注解的原理解析-注解方式注解整合MyBatis框架注解整合第三方框架引子 痛定…

一篇文章让你搞懂Java顺序表

目录 一、 线性表的基本介绍 二、顺序表 1、顺序表的概念 2. 创建顺序表类&#xff08;ArrayList&#xff09; 2. 增加元素 3. 删除元素 4. 修改某个元素 5. 查找元素 Main类 在数据结构体系中我们将整个数据结构分为两类&#xff0c;一类是线性结构&#xff1b; 线性…

微电网两阶段鲁棒优化经济调度方法(完美复现)

针对微电网内可再生能源和负荷的不确定性&#xff0c;建立了 min-max-min 结构的两阶段鲁棒优化模型&#xff0c;可得到最恶劣场 景下运行成本最低的调度方案。模型中考虑了储能、需求侧 负荷及可控分布式电源等的运行约束和协调控制&#xff0c;并引入了 不确定性调节参数&…

Java基于springboot+vue+element医疗用品销售购物商城系统 前后端分离

开发背景和意义 网络购物己经成为一个常态化的消费手段&#xff0c;足不出户即可享受互联网发展的红利&#xff0c;对于购物商城的应用&#xff0c;普通消费者目前普遍使用。医疗用品作为一个大众消费的商品&#xff0c;由于其健康的特点&#xff0c;也越来越为大家喜欢&#…

TypeScript 知识点总结

对于有着强制类型语言经验的开发来讲&#xff0c;刚开始接触 JavaScript 的时候&#xff0c;大多都有一种 “心如芒刺&#xff0c;如鲠在喉” 的感觉。 从最初的好感 -——开放包容&#xff0c;到后来的厌恶之情——放荡不羁 TypeScript 犹如黑暗之中的一缕阳光&#xff0c;拯救…

【单片机基础】ADC0832详解

文章目录一、ADC0832介绍1、功能特点2、引脚说明3、ADC0832与单片机接口4、工作时序二、例程一、ADC0832介绍 ADC0832 是美国国家半导体公司生产的一种8 位分辨率、双通道A/D转换芯片。由于它体积小&#xff0c;兼容性&#xff0c;性价比高而深受单片机爱好者及企业欢迎&#x…

Java_笔记_static_静态变量方法工具类_main方法

static表示静态&#xff0c;是Java中的一个修饰符&#xff0c;可以修饰成员方法和成员变量。 一、静态变量: 被static修饰的成员变量 1.特点&#xff1a; 1&#xff09;被该类所有的对象共享。 2&#xff09;不属于对象&#xff0c;属于类。 3&#xff09;随着类的加载而加载…

(个人记录)Ensight后处理EDEM学习笔记

①EDEM计算完毕 ②左上角,点击输出data 先点击一下 然后再把EXPORT FORMAT改为ensight的格式 file name选择要保存到的文件夹,保存格式为.case文件 设置保存的时间步 填入“10”的意思是0.01*10=0.1,在ensight中以0.1的时间步展示结果 点击queries 在ensight里只能…

七段显示译码器

我们会把它放在系统中来显示多位&#xff0c;很多位的表达会用到小数点 12.34 我只想显示&#xff0c;我现实系统的数字大小有一个范围&#xff0c;比如整数四位&#xff0c;小数四位 我显示12.34 就意味着首先两位就是空着&#xff0c;最后两位也是空着 这几位从输入的数字…

Android 基础知识4-1 用户界面简介VIewGroup、Onclick事件处理

引言&#xff1a; 一个好的应用界面的必备条件是&#xff1a;内容清楚、指示明白、屏幕美观和有亲切感。界面通常包含图形和文字。应用界面的设计是对控件进行适当的取舍及功能的选择和处理的过程。在程序设计中&#xff0c;需要对设计的方法反复推敲、琢磨&#xff0c;才能使其…

spfa算法判断负环【什么是负环】【出现负环会怎么样】【牢记,此时不是求最短路】

欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09; 文章字体风格&#xff1a; 红色文字表示&#xff1a;重难点 蓝色文字表示&#xff1a;思…

【推荐题目】

一&#xff0c;题目 1. 猪队友&#xff08;pigmate.cpp&#xff09; 【问题描述】 "不怕神一样的对手&#xff0c;就怕猪一样的队友"&#xff0c;这不&#xff0c;小A需要将小B写的 n 张不同的明信片 放到一一对应的 n 个不同的信封中去&#xff0c;可是不管你信不…

代码不到200行!Tkinter上课点名程序来了

前言 今天给大家分享一个比较有意思的Python应用&#xff0c;使用Tkinter开发了一款上课点名程序&#xff0c;此程序可以用于点名、抽奖代码不到200行&#xff0c;程序简单又实用&#xff0c;分享给到大家&#xff5e; 开发工具 Python版本&#xff1a; 3.8 相关模块&#xff1…

I2C、SPI、CAN、PCIe 对比

唯一标识 在社会上&#xff0c;靠身份证号&#xff0c;来唯一标识一个人。 在计算机的世界里&#xff0c;通过什么来唯一标识一个外设呢&#xff1f;方案还不止一种 I2C 使用地址&#xff08;7 或 10 位&#xff09;来唯一标识一个外设 SPI 使用 CS 引脚来唯一确定通信的外设…

0.安装和配置

我们不要怕&#xff0c;我们要一直向前&#xff0c;为了我们的目标。 对应关系是: https://www.rabbitmq.com/which-erlang.html 安装 Erlang https://www.erlang.org/downloads 选中 64 位 进行下载 下载后&#xff0c;双击 进行安装 选择 安装的路径 路径为&#xff1a; …

[附源码]计算机毕业设计校园招聘系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…