网站做收录是什么意思/今日重大新闻事件
深浅拷贝
- 问题引入
- 浅拷贝
- 深拷贝
- 总结
问题引入
对于一个普通的string类:
class String {
public:String(const char* str = ""){//构造函数if (nullptr == str)str = "";_str = new char[strlen(str) + 1];strcpy(_str, str);}~String(){//析构函数if (_str) {delete[] _str;_str = nullptr;}}
private:char* _str;
};
浅拷贝
对于上述的 String 类来说,浅拷贝也就是将一个对象原封不动的复制粘贴到新的对象当中,当类中没有给定拷贝构造函数时系统会默认生成一个拷贝构造函数,但默认生成的拷贝构造函数就属于浅拷贝:
当前系统默认生成的拷贝构造函数类似于:
那么,浅拷贝是否合理存在?
由上述运行截图我们可以观察到使用系统默认生成的拷贝构造函数或是代码中展现的拷贝构造方法构造出来的对象与原对象内容地址是完全一致的,也就类似于复制粘贴了一个相同的对象,那么它会产生什么问题?
在前边类与对象章节中,我们知道了在创建的类对象使用结束之后系统会自动调用相应的析构函数来释放资源空间(先构造的后释放,后构造的先释放),因此在该类中,首先要进行释放的是 s2,后释放 s1,我们来看看现象:
不知道,读者是否发现了问题所在?
解析:
在使用 s2(s1),s1拷贝构造 s2 对象时,我们发现创建出来的 s2 对象完全是复制粘贴 s1 对象而形成的,不仅对象内容完全相同,对象的地址空间也完全相同,这就导致了两个对象是共享同一份地址空间了,故在进行析构时,产生了同一份地址空间二次释放而发生异常提示
同理,在 String 类中倘若用户没有显式定义赋值运算符重载函数,则系统会默认生成一个赋值运算符重载函数,我们来看看会有什么问题?
显然,同样产生了浅拷贝(复制粘贴),则在进行空间销毁时候定会产生空间的二次释放异常,那么我们应该如何来解决这种问题?
介绍两种技术:深拷贝(重点)、写时拷贝
深拷贝
产生浅拷贝的主要是因为在进行拷贝构造或是赋值运算符重载时,直接将就对象的内容原封不动的粘贴给新对象,因而在空间释放时形成了多次释放问题,因此深拷贝主要就是解决不同对象分配不同地址空间的问题:
String(const String& s):_str(nullptr){//s2(s1)//首先需要给s2对象开辟一份独立的新空间_str = new char[strlen(s._str) + 1];//其次将s1对象中的内容拷贝到s2空间当中strcpy(_str, s._str);}
同理,赋值运算符也是一样的:
String& operator=(const String& s){if (this != &s) //判断不是自己给自己赋值{char* tmp = new char[strlen(s._str) + 1];strcpy(tmp, s._str);delete[] _str; //释放旧空间_str = tmp;}return *this;}
显然,两个对象的地址空间是不相同的,则释放空间时不会发生同一份空间多次释放的问题。
现代新写法(注意理解):
String(const String& s):_str(nullptr){//拷贝构造函数String tmp(s._str); //采用当前对象的内容构造出一个新对象tmpswap(_str,tmp._str); //进行资源交换,将临时空间 tmp 的内容与 当前对象的内容进行交换------------临时对象在函数周期结束自动析构释放}String& operator=(String s) { //以值的方式传参,需要调用一次拷贝构造函数,构造出一个新的对象 s//赋值运算符重载if (this != &s) {swap(_str, s._str); //直接进行交换}return *this;}
总结
在类中,倘若用户没有显式定义拷贝构造函数以及赋值运算符重载函数,则编译器会自动生成一份,但在使用时属于浅拷贝会造成同一份空间多个对象共享,在对象使用结束释放空间时会发生多次释放问题产生,其次在赋值运算符重载函数中,不仅会使得多个对象共享空间,还会导致空间丢失问题:
String s1("hello"); //调用构造String s2 = "world";//使用系统默认生成的赋值运算符重载函数会导致原有的 s2 对象空间泄漏s2 = s1;
因此, 我们应该在使用时进行显式的定义,防止发生浅拷贝问题的产生
写时拷贝技术
写时拷贝技术同样是针对浅拷贝问题的解决方式
允许多个对象共享同一份地址空间以及空间中的内容,并定义一个计数器来统计当前空间所共享的对象个数,并在对象使用结束之后在析构函数内部进行计数器 - 1,当析构一个对象之后,计数器变为 0,说明当前对象是共享空间的最后一个使用者,则需要对这块空间进行释放--------------------------------但同样存在一个问题:倘若某一个对象对这块共享空间的内容进行了修改,则其他对象指向的这块共享空间内容也发生了变化
因此,写时拷贝技术是在对象需要对共享的内存空间进行修改时拷贝构造出独立的空间来进行修改,这么做就不会影响到其他对象对共享空间的访问。
ps:
博文内容为原创,欢迎各位共同学习~~
相关文章:

string的深浅拷贝问题
深浅拷贝问题引入浅拷贝深拷贝总结问题引入 对于一个普通的string类: class String { public:String(const char* str ""){//构造函数if (nullptr str)str "";_str new char[strlen(str) 1];strcpy(_str, str);}~String(){//析构函数if …...

C++中的万能头文件
目录一、什么是万能头文件?二、源码三、编译器找不到 bits/stdc.h一、什么是万能头文件? C的万能头文件是: #include <bits/stdc.h>它是一个包含了每一个标准库的头文件。 优点: 在算法竞赛中节约时间;减少了…...

Java 8 Lambda 表达式 Stream
lambda表达式和Stream流是JDK8新增加的新特性,研究本文内容或者运行本文中的demo示例必须安装并使用JDK8以上的JDK版本。demo地址:https://gitee.com/huannzi/bigdataframework/tree/master/src/main/java/com/orkasgb/java 文章目录1、什么是Lambda表达…...

【VictoriaMetrics】VictoriaMetrics单机版部署(二进制版)
1、下载安装包git路径,本文基于1.87.1版本 进入git地址 :https://github.com/VictoriaMetrics/VictoriaMetrics/tags 2、下载其中linux下的 amd64架构...

SCI论文阅读-使用基于图像的机器学习模型对FTIR光谱进行功能组识别
期刊: Analytical Chemistry中科院最新分区(2022年12月最新版):1区(TOP)影响因子(2021-2022):8.008第一作者:Abigail A. Enders通讯作者:Heather C. Allen 原文链接&…...

双11大型互动游戏“喵果总动员” 质量保障方案总结
推荐语:互动游戏是一个系统化工程,在笔者的“喵果总动员”质量方案中,可以看到为保障用户体验,我们在各个难点的解决方案, 例如:用线上压测能力支持业务及时调整各服务容量、通过强化学习覆盖游戏行业的测试…...

剑指Offer专项突击版题解一
1.整数除法 思想:不能用除法、乘法、取余,那么可以用减法完成除法的操作,但是在减去被除数的时候,可以考虑被除数<<1扩大一倍在进行减少,加快减的速率。 2.二进制加法 思想:从末尾向前遍历࿰…...

Django框架之模型
模型 当前项目的开发, 都是数据驱动的。 以下为书籍信息管理的数据关系:书籍和人物是 :一对多关系 要先分析出项目中所需要的数据, 然后设计数据库表. 书籍信息表 字段名字段类型字段说明idAutoField主键nameCharField书名 idname1西游记2三国演义…...

OSACN-Net:使用深度学习和Gabor心电图信号谱图进行睡眠呼吸暂停分类
这篇文章在之前读过一次,其主要的思路就是利用Gabor变换,将心电信号转变为光谱图进行识别研究,总体来讲,不同于其他的利用心电信号分类的算法,该论文将心电信号转换为光谱图,在此基础上,分类问题…...

使用开源实时监控系统 HertzBeat 5分钟搞定 Mysql 数据库监控告警
使用开源实时监控系统 HertzBeat 对 Mysql 数据库监控告警实践,5分钟搞定! Mysql 数据库介绍 MySQL是一个开源关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的开源关系型数据库管理系统之…...

插件 sortablejs:HTML元素可拖动排序
插件 sortablejs 用于可重新排序拖放列表的JavaScript库;关键链接:npm 地址 Github 地址 安装 npm i sortablejs引入 import Sortable from "sortablejs"HTML <ul id"items"><li>item 1</li><li>item …...

libVLC 视频裁剪
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 裁剪是指去除图像的外部部分,也就是从图像的左,右,顶部和/或底部移除一些东西。通常在视频中,裁剪是一种通过剪切不需要的部分来改变宽高比的特殊方式。 尤其是在做视频墙时,往往需要处理多个 vlc 实例…...

LAMP架构介绍及配置
LAMP架构介绍及配置一、LAMP简介与概述1、LAMP平台概述2、LAMP各组件主要作用3、构建LAMP平台二、编译安装Apache htpd服务1、将所需软件包上传到/opt目录下2、解压以下文件3、移动两个文件并改名4、安装所需工具5、编译安装6、做软连接,使文件可执行7、优化配置文件…...

Android图形显示流程简介
注:本文缩写说明本文代码都是基于Android S一、概述本文将对从App画出一帧画面到这帧画面是如何到达屏幕并最终被人眼看到的这一过程进行简要分析,并将这其中涉及到的各个流程与其在systrace上的体现对应起来,期望最终能够让读者对Android系统…...

4.5.3 ArrayList
文章目录1.特点2. 练习:ArrayList测试3.ArrayList扩容1.特点 存在java.util包中内部是用数组结构存放数据,封装数组的操作,每个对象都有下标内部数组默认的初始容量是10,如果不够会以1.5倍的容量增长查询快,增删数据效率会低 2. 练习:ArrayList测试 package partThree;import…...

十二、Linux文件 - fseek函数讲解
目录 一、fseek函数讲解 二、fseek函数实战 一、fseek函数讲解 重定向文件内部的指针 注:光标 ---- 文件内部的指针 函数原型: int fseek(FILE *stream,long offset,int framewhere) 参数: stream:文件指针offset:…...

Python3.10新特性之match语句示例详解
这篇文章主要为大家介绍了Python3.10新特性之match语句示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪正文在Python 3.10发布之前,Python是没有类似于其他语言中switch语句的&…...

虎牙盈利能力得到改善,但监管风险对其收入产生负面影响
来源:猛兽财经 作者:猛兽财经 监管风险再次成为焦点 过去一段时间,与中概股相关的监管风险再次引起了投资者的注意,这也是正在考虑投资虎牙(HUYA)的投资者需要注意的问题。 例如,监管机构在2022…...

HBase 分布式搭建
前言: 请先确保 Hadoop 集群搭建完成。 Hadoop 完全分布式搭建(超详细)搭建环境介绍: 三台主机,一主两从,系统为 Centos 7.5。 相关组件版本信息如下: jdk1.8hadoop-3.1.3zookeeper-3.5.7hbase-2.2.3注意,以下安装教程中涉及到的路径请替换成自己的! ZooKeeper 安…...

【Python】修改枚举的取值及链式调用
author: jwensh date: 2023.02.11 文章目录枚举的取值及链式调用需求背景1. enum.key 即获取值(而不是 enum.key.value)2. 多级链式调用枚举的取值及链式调用 需求背景 测试过程中需要很多参数化的设置及编程规范要求,希望修改数据不修改代…...

复现篇--zi2zi
intro: 用GAN学习东亚语言字体。zi2zi(意思是从字符到字符)是最近流行的pix2pix模型在汉字上的应用和扩展。 article:https://kaonashi-tyc.github.io/2017/04/06/zi2zi.html code:https://github.com/kaonashi-tyc/zi2zi pytorch版本:https://github.com/EuphoriaYan/zi2…...

153、【动态规划】leetcode ——416. 分割等和子集:滚动数组(C++版本)
题目描述 原题链接:1049. 最后一块石头的重量 II 解题思路 本题要找的是最小重量,我们可以将石头划分成两个集合,当两个集合的重量越接近时,相减后,可达到的装量就会是最小,此时本题的思路其实就类似于 4…...

linux head命令(head指令)(获取文件或管道输出结果前n行,默认前10行)与sed命令区别
head命令是一个在Linux系统中常用的命令,用于读取文件的前几行(默认读取前10行) 文章目录使用方法读取文件的前10行:head filename读取文件的前n行:head -n行数 filename读取多个文件的前几行:head -n 行数…...

Mysql数据库09——分组聚合函数
类似pandas里面的groupby函数,SQL里面的GROUP BY子句也是可以达到分组聚合的效果。 常用的聚合函数有COUNT(),SUM(),AVG(),MAX(),MIN(),其用法看名字都看的出来,下面一一介绍 聚合函数 COUNT()计数 统计student表中计科系学生的人数。 SE…...

第43章 菜单实体及其约束规则的定义实现
1 Core.Domain.Security.Menu namespace Core.Domain.Security { /// <summary> /// 【菜单--类】 /// <remarks> /// 摘要: /// 通过该实体类及其属性成员,用于实现当前程序【Core】.【领域】.【安全】.【菜单】实体与“[ShopDemo].[…...

OpenAI最重要的模型【CLIP】
最近的 AI 突破 DALLE和 Stable Diffusion有什么共同点? 它们都使用 CLIP 架构的组件。 因此,如果你想掌握这些模型是如何工作的,了解 CLIP 是先决条件。 此外,CLIP 已被用于在 Unsplash 上索引照片。 但是 CLIP 做了什么&…...

分享112个JS菜单导航,总有一款适合您
分享112个JS菜单导航,总有一款适合您 112个JS菜单导航下载链接:https://pan.baidu.com/s/1Dm73d2snbu15hZErJjTXxg?pwdfz1c 提取码:fz1c Python采集代码下载链接:https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "h…...

MySQL 3:MySQL数据库基本操作 DQL
数据库管理系统的一个重要功能是数据查询。数据查询不应简单地返回数据库中存储的数据,还应根据需要对数据进行过滤,确定数据的显示格式。MySQL 提供了强大而灵活的语句来实现这些操作。MySQL数据库使用select语句查询数据。 select [all|distinct]<…...

sql语句的优化
sql优化 优化数据访问 查询性能低下最基本的原因是访问的数据太多,大部分性能低下的查询都可以通过减少访问的数据量来优化所以关于低效的查询,需要确认是否检索了大量不需要的数据,以及mysql服务器层是否在分析大量不需要的数据 因为有些查…...

Shell脚本之——自动安装JDK
目录 1.修改主机名 2.创建文件,单独存放Shell脚本 3.编写Shell脚本 4.Shell脚本命令简介 (1)文件头 (2)打印命令 (3)设置全局变量 (4)条件判断 (5)解压 (6)文件重命名 (7)在/etc/profile指定行插入 5.完整脚本内容 6.重启环境变量 7.判断java是否配置…...