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

string的深浅拷贝问题

深浅拷贝

  • 问题引入
  • 浅拷贝
  • 深拷贝
  • 总结

问题引入

对于一个普通的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++中的万能头文件

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

Java 8 Lambda 表达式 Stream

lambda表达式和Stream流是JDK8新增加的新特性&#xff0c;研究本文内容或者运行本文中的demo示例必须安装并使用JDK8以上的JDK版本。demo地址&#xff1a;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光谱进行功能组识别

期刊&#xff1a; Analytical Chemistry中科院最新分区&#xff08;2022年12月最新版&#xff09;&#xff1a;1区(TOP)影响因子&#xff08;2021-2022&#xff09;&#xff1a;8.008第一作者&#xff1a;Abigail A. Enders通讯作者&#xff1a;Heather C. Allen 原文链接&…...

双11大型互动游戏“喵果总动员” 质量保障方案总结

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

剑指Offer专项突击版题解一

1.整数除法 思想&#xff1a;不能用除法、乘法、取余&#xff0c;那么可以用减法完成除法的操作&#xff0c;但是在减去被除数的时候&#xff0c;可以考虑被除数<<1扩大一倍在进行减少&#xff0c;加快减的速率。 2.二进制加法 思想&#xff1a;从末尾向前遍历&#xff0…...

Django框架之模型

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

OSACN-Net:使用深度学习和Gabor心电图信号谱图进行睡眠呼吸暂停分类

这篇文章在之前读过一次&#xff0c;其主要的思路就是利用Gabor变换&#xff0c;将心电信号转变为光谱图进行识别研究&#xff0c;总体来讲&#xff0c;不同于其他的利用心电信号分类的算法&#xff0c;该论文将心电信号转换为光谱图&#xff0c;在此基础上&#xff0c;分类问题…...

使用开源实时监控系统 HertzBeat 5分钟搞定 Mysql 数据库监控告警

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

插件 sortablejs:HTML元素可拖动排序

插件 sortablejs 用于可重新排序拖放列表的JavaScript库&#xff1b;关键链接&#xff1a;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、做软连接&#xff0c;使文件可执行7、优化配置文件…...

Android图形显示流程简介

注&#xff1a;本文缩写说明本文代码都是基于Android S一、概述本文将对从App画出一帧画面到这帧画面是如何到达屏幕并最终被人眼看到的这一过程进行简要分析&#xff0c;并将这其中涉及到的各个流程与其在systrace上的体现对应起来&#xff0c;期望最终能够让读者对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函数讲解 重定向文件内部的指针 注&#xff1a;光标 ---- 文件内部的指针 函数原型&#xff1a; int fseek(FILE *stream,long offset,int framewhere) 参数&#xff1a; stream&#xff1a;文件指针offset&#xff1a;…...

Python3.10新特性之match语句示例详解

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

虎牙盈利能力得到改善,但监管风险对其收入产生负面影响

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 监管风险再次成为焦点 过去一段时间&#xff0c;与中概股相关的监管风险再次引起了投资者的注意&#xff0c;这也是正在考虑投资虎牙&#xff08;HUYA&#xff09;的投资者需要注意的问题。 例如&#xff0c;监管机构在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 即获取值&#xff08;而不是 enum.key.value&#xff09;2. 多级链式调用枚举的取值及链式调用 需求背景 测试过程中需要很多参数化的设置及编程规范要求&#xff0c;希望修改数据不修改代…...

Linux栈机制解析:进程栈、线程栈与内核栈

Linux系统中的栈机制深度解析&#xff1a;进程栈、线程栈、内核栈与中断栈1. 栈的基本原理与硬件实现栈(Stack)是一种后入先出(LIFO)的串列数据结构&#xff0c;在计算机体系结构中具有重要作用。硬件层面&#xff0c;大多数处理器架构都实现了专门的栈机制&#xff1a;栈指针寄…...

Claude模型选型指南:Opus/Sonnet/Haiku三大系列在真实项目中的性能价格对比

Claude模型选型实战&#xff1a;Opus/Sonnet/Haiku三大系列性能与成本深度评测 1. 企业级AI选型的核心考量 在构建商业AI解决方案时&#xff0c;技术决策者往往面临模型选型的复杂权衡。Anthropic推出的Opus、Sonnet和Haiku三大系列&#xff0c;分别针对不同规模和应用场景的…...

告别阿里云!用ThingsCloud免费搭建个人智能家居控制中心(附ESP8266配置)

从零构建智能家居控制中心&#xff1a;ThingsCloud与ESP8266实战指南 在智能家居领域&#xff0c;许多技术爱好者常常面临一个两难选择&#xff1a;要么使用功能强大但配置复杂的商业平台&#xff0c;要么选择简单但功能有限的DIY方案。ThingsCloud的出现为这一问题提供了优雅的…...

python vue医院健康体检系统

目录技术选型与架构设计核心模块划分关键功能实现安全与合规措施部署方案开发里程碑计划项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术选型与架构设计 后端采用Python的Django框架&#xff0c;提供RESTful API接口。Djan…...

3步打造专属音乐库:开源工具解锁无损音质体验

3步打造专属音乐库&#xff1a;开源工具解锁无损音质体验 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 作为一款功能强大的开源音乐资源工具&#xff0c;洛雪音乐音源整合了全网海量音乐资源&am…...

Verilog条件语句实战:如何避免if-else嵌套中的常见陷阱?

Verilog条件语句实战&#xff1a;如何避免if-else嵌套中的常见陷阱&#xff1f; 在数字电路设计中&#xff0c;条件语句的正确使用直接关系到电路的功能实现和性能表现。Verilog作为硬件描述语言&#xff0c;其if-else和case语句的灵活运用是每位工程师必须掌握的技能。但看似简…...

Python异步服务部署与无服务器架构实践指南

Python异步服务部署与无服务器架构实践指南 【免费下载链接】uvicorn An ASGI web server, for Python. &#x1f984; 项目地址: https://gitcode.com/GitHub_Trending/uv/uvicorn 在云原生应用开发领域&#xff0c;Python异步服务部署正成为构建高性能后端系统的首选方…...

重构ComfyUI工作流:从混乱到高效的节点优化实践

重构ComfyUI工作流&#xff1a;从混乱到高效的节点优化实践 【免费下载链接】ComfyUI-KJNodes Various custom nodes for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-KJNodes 一、问题发现&#xff1a;识别工作流中的效率瓶颈 1.1 视觉复杂性诊断 …...

Fluent Bit源码解析:KISS原则如何打造轻量级日志处理神器

Fluent Bit源码解析&#xff1a;KISS原则如何打造轻量级日志处理神器 【免费下载链接】fluent-bit Fast and Lightweight Logs and Metrics processor for Linux, BSD, OSX and Windows 项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit 在当今云原生时代&…...

Visual C++运行时组件故障解决完全指南:从问题定位到能力提升

Visual C运行时组件故障解决完全指南&#xff1a;从问题定位到能力提升 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行时组件&#xff08;Microsof…...