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

C++:string类写时拷贝|引用计数


Blog’s 主页: 白乐天_ξ( ✿>◡❛)
🌈 个人Motto:他强任他强,清风拂山冈!
💫 欢迎来到我的学习笔记!

写时拷贝(了解)

参考博客:C++写时拷贝的不同方案(String类)_c++ string 从第三个字节拷贝-CSDN博客

1.1 概念

  • 在此之前,我们就有讲过深浅拷贝的问题
    • 浅拷贝会导致同一块空间析构两次;
    • 一个对象进行修改等变化会影响另一个对象(因为同一个地址同一块空间)
  • 因此我们使用深拷贝解决该问题:先开辟空间后拷贝数据。但是这种方法需要我们没创建一个对象就去深拷贝,可在后面该对象并没有做任何修改操作,那么深拷贝的作用就不大了,而且还浪费了内存空间资源。(深拷贝:每次对对象进行值和空间同时拷贝,但是会使用更多的空间
  • 因此就有了写时拷贝。当对空间进行修改时,检查出来自己以外是否还有其他对象使用此空间。有,自己重新开辟空间进行修改,不去影响其他对象;没有,则表示是自己空间资源独享,直接进行更改。而这里引入引用计数,用于统计有多少对象在使用这块空间资源

1.2 方案1

画板

  • 当创建出一个对象s1,利用s1拷贝构造出一个对象s2,引用技术refCount自动+1,此时值为2。
  • 如果现在要对s2进行自身的修改操作,先判断refCount是否大于1。若大于1,则s2要重新开辟一块空间,然后再进行修改操作,避免影响其他对象。

画板

  • s2重新开辟了一块空间,然后再修改原来的引用计数refCount,使其-1;重新开辟的空间中因为此时只有一个对象,所以引用计数refCount也是1。

总结:此方案的写时拷贝技术是同时开辟两块空间,一块用于存放自身的内容,另一块用于存放引用计数refCount,同时管理两块空间,统计当前使用此空间的对象数,当要修改当前空间的时候,进行引用计数的判断,再决定是否开辟新空间。

class String
{
public:
	//构造函数
	String(char* str="")
		:_str(new char[strlen(str)+1])
		,_refCount(new int(1))
	{
		strcpy(_str, str);
	}
 
 
	//拷贝构造函数
	String(String& s)
	{
		_str = s._str;
		_refCount = s._refCount;
		++(*_refCount);
	}
 
	String& operator=(const String& s)
	{
		if (_str != s._str)
		{
			Release();
 
			_str = s._str;
			_refCount = s._refCount;
			(*_refCount)++;
		}
		return *this;
	}
 
	void Release()
	{
		if (--(*_refCount) == 0)
		{
			cout << "delete" << endl;
			delete[] _str;
			delete _refCount;
		}
	}
 
	~String()
	{
		Release();
	}
 
	void CopyOnWrite()
	{
		if (*_refCount > 1)
		{
			char* tmp = new char[strlen(_str) + 1];
			strcpy(tmp, _str);
			--(*_refCount);
 
			_str = tmp;
			_refCount = new int(1);
		}
	}
 
	char& operator[](size_t pos)
	{
		CopyOnWrite();
		return _str[pos];
	}
 
	char operator[](size_t pos) const
	{
		return _str[pos];
	}
private:
	char* _str;
	int* _refCount;
};

1.3 方案2

  • 开辟两块空间同时进行管理,方案2只开辟一块空间进行写时拷贝操作。

画板

  • 在对对象进行操作时,先检查引用计数的个数,然后再判断是否开辟新的空间,同时修改引用计数的值,防止空间不能释放。
  • 例如:当创建的3个对象s1、s2、s3同时指向一个空间时,再创建一个对象s4,s4的引用计数为1。

画板

再进行s3 = s4操作,此时对应的引用计数和对应的指向都需要进行修改,更改后图形如下:

画板

  • 此时对象s3指向了s4,同时原来的空间的引用计数进行-1操作 ,新指向空间的引用计数进行+1操作,而且不用开辟两块空间。


http://www.kler.cn/a/320770.html

相关文章:

  • VMWare虚拟机安装华为欧拉系统
  • 计算机组成原理笔记----基础篇
  • wordpress使用相关
  • 前端Javascript、Vue、CSS等场景面试题目(二)
  • 若点集A=B则A必能恒等变换地变为B=A这一几何常识推翻直线(平面)公理
  • 【WPF】Prism学习(三)
  • git使用方法详解(适合新手)
  • 找免费正版高清图片,就上这8个网站。
  • 深度拆解:如何在Facebook上做跨境电商?
  • 【docker】debian中配置docker(2024年9月)
  • YOLOv8-pose+streamlit 实现人体关键点检测/姿态估计系统(后续可用于健身时的姿态估计,训练纠正等....)
  • 智算中心动环监控:构建高效、安全的数字基础设施@卓振思众
  • 从Unity到Godot
  • Ubuntu22.04安装paddle
  • 超越sora,最新文生视频CogVideoX-5b模型分享
  • 4.SPI外设—LCD小案例
  • 拓数派荣获上海数据交易所“数据治理服务商”认证
  • 无线领夹麦克风哪个牌子好,2024年新款领夹麦克风推荐
  • 回归预测 | Matlab基于SO-SVR蛇群算法优化支持向量机的数据多输入单输出回归预测
  • 【监控体系搭建一】Docker安装与使用
  • 万界星空科技铜拉丝行业MES系统,实现智能化转型
  • Prometheus使用Pushgateway推送数据
  • 【数据结构】栈和队列(Stack Queue)
  • 统信服务器操作系统ade版【iostat】命令详解
  • LeetCode 136. 只出现一次的数字
  • 三,MyBatis-Plus 的各种查询的“超详细说明”,比如(等值查询,范围查询,模糊查询...)