【C++】模拟实现string类(版本二:用写时拷贝来实现)

《C++ string 完全指南:string的模拟实现》 本文中作者讲述了string的模拟实现以各个接口的细节与图解!让你更清晰地感受STL的魅力 阅读详情

1.什么是写时拷贝

     介绍写时拷贝之前,我们得先了解一下深浅拷贝,浅拷贝简单来说就是:只是对指针的拷贝,拷贝后和原来的指针指向同一块空间,如图:


    所以,浅拷贝其实存在很多问题:

        1.由于都指向同一块空间,所以,一旦其中一个对其内容做了更改,则所有对象都会发生变化,显然这并不是我们想要的。

        2.很容易造成同一块空间被释放两次,因为都指向同一块空间。

        3.很容易造成内存泄漏

    深拷贝即不止对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。



     深拷贝解决了浅拷贝存在的那些问题,但是如果每次都给对象开辟内存,但是不一定会进行更改,岂不是会浪费内存?所以写时拷贝出现了

那么写时拷贝是什么意思呢?

   顾名思义,就是在程序要进行写入操作是进行深度拷贝,否则进行浅拷贝,设置一个引用计数(与空间绑定在一起),当又有新指针指向这块空间时,引用计数+1,析构时,先检测引用计数是否为1,若为1则直接释放,否则,引用计数-1即可。有兴趣的读者可以验证一下,在Windows下,string是用深度拷贝的方式实现的,但是在Linux下,string是用写时拷贝的方式实现的。

2.写时拷贝string的部分实现:

#define _CRT_SECURE_NO_WARNINGS 1 
#include<iostream>
#include<cstring>
using namespace std;

class String
{
	friend ostream &operator<<(ostream &os, const String & s);
public:
	String(char *str = "")
		:_str(new char [strlen(str) + 5])   //将引用计数器和字符串放在同一块空间
	{
		_str += 4;
		GetCount()=1;            //取到引用计数器的空间并赋为1.
		strcpy(_str, str);
	}
	~String()
	{
		Release();         //为增强代码的复用性,封装了一个释放空间的函数
	}
	String(const String & s)
		:_str(s._str)
	{
		GetCount()++;
	}
	String& operator=( String& s)
	{
		if (this != &s)        //判断是否自己给自己赋值
		{
			Release();
			_str = s._str;
			++GetCount();
		}
		return *this;
	}
	char &operator[](size_t index)    //写时,深度拷贝
	{
		if (GetCount() > 1)           
		{
			GetCount()--;
			char *tmp = new char[strlen(_str) + 5];
			strcpy(tmp+4, _str);
			_str = tmp+4;
			GetCount()++;
		}
		return _str[index];
	}
private:
	int& GetCount()            //得到引用计数空间并以引用的方式返回,方便计数器改变
	{
		return *(int *)(_str - 4);
	}
	void Release()
	{
		if (GetCount() == 0)
		{
			delete[](_str - 4);
		}
	}
private:
	char* _str;
};
ostream &operator<<(ostream &os, const String & s)
{
	os << s._str << "";
	return os;
}
void test1()
{
	String s1("hello");
	String s2(s1);
	String s3("world");
	s2 = s3;
}

void test2()
{
	String s("hello");
	s[2] = 'q';
	cout << s << endl;
}

int main()
{
	test1();
	test2();
	getchar();
	return 0;
}


    

C++string类 🔥在C++中,迭代器(lterator)是用于访问和遍历容器(如vector、list、map等)元素的核心工具,其本质是一个类似指针的对象,但提供了更统一的抽象接口,能够屏蔽不同容器的底层实现细节。(1) 迭代器的核心特性1.功能定义迭代器通过指针式的操作(如递增、解引用等)访问容器元素,通常支持以下基本操作:● 指向容器中的元素(类似指针)。● 通过++或 – 移动位置(支持单向或双向移动,取决于迭代器类型● 通过*操作符访问或修改元素值。2.核心作用。 阅读详情

相关推荐

DIY便携式PEMF磁脉冲治疗仪:百元成本自制生物物理疗法设备

脉冲电磁场(PEMF)疗法是一种基于生物物理原理的非侵入性技术,它通过特定频率的电磁脉冲作用于细胞层面,影响细胞膜电位和离子通道活动,从而可能调节细胞代谢与功能。其技术价值在于提供了一种物理干预手段,在健康科技和生物黑客领域被探索用于放松、恢复等场景。实现PEMF的核心是通过信号发生与功率放大驱动电磁线圈产生可控磁场。本文以蓝牙音频模块和智能手机App为切入点,详细解析了如何利用低成本电子元件(如DFRobot XY-WRBT模块和漆包线线圈)构建一个可自定义频率的便携式PEMF设备,涵盖了从电路设计、线圈

weixin_31476015的博客 352

类和动态内存分配(2)

C++ Primer Plus -- 指向对象的指针,使用定位new运算符为对象分配内存空间

GodFishhh的博客 727

Second-Order Cone Programming(SOCP) 二阶锥规划

个人博客Glooow,欢迎各位老师来踩踩 文章目录1. 二阶锥1.1 二阶锥定义1.2 二阶锥约束2. 优化问题建模3. 类似问题转化3.1 二次规划3.2 随机线性规划4. 问题求解 1. 二阶锥 1.1 二阶锥定义 在此之前,先给出二阶锥的定义。 在 kkk 维空间中二阶锥 (Second-order cone) 的定义为 Ck={[ut]∣u∈Rk−1,t∈R,∥u∥≤t} \mathc...

Glooow的博客 3万+

Primer C++ 学习笔记(第十四章)

Primer C++ 学习笔记(第十四章)

胖狗子修行之路的博客 422

C#实战:如何用Bartender 10.1实现动态打印与批量打印(附完整源码)

本文深入探讨了如何在C#项目中高效集成Bartender 10.1,实现企业级的动态打印与批量打印功能。文章提供了从环境配置、COM接口精讲、高可用打印服务类封装,到批量打印性能优化及生产环境部署的全套实战方案与源码,帮助开发者构建健壮、可维护的打印解决方案。

weixin_29290963的博客 436

物理小白也能懂的PINN指南:用Python给神经网络注入‘物理常识‘

本文为物理小白提供了一份通俗易懂的PINN入门指南。通过生活化类比和Python实战,详细讲解了如何将物理定律作为约束注入神经网络,使其具备“物理常识”,从而在数据稀缺时也能做出符合规律的预测。文章以热传导方程为例,手把手教你从零构建物理信息神经网络。

open4的博客 349

C++ Primer Plus 第6版 第12章 编程练习答案

1. 对于下面的类声明: class Cow { private: char name[20]; char* hobby; double weight; public: Cow(); Cow(const char* nm, const char* ho, double wt); Cow(const Cow& c); ~Cow(); Cow& operator=(const Cow& c); void Show...

Anna_L的博客 503

基于Python的军事装备数据爬取与分析:从网页抓取到数据可视化实战

本文将详细介绍如何使用Python最新技术栈构建一个完整的军事装备数据爬虫系统。我们将从爬虫基础讲起,逐步深入到异步爬取、反反爬策略、数据存储与分析等高级主题,最终实现一个能够自动抓取、清洗、存储和分析军事装备数据的完整解决方案。文章包含大量实战代码示例,涉及requests-html、aiohttp、Playwright等现代爬虫库,以及MongoDB存储、Pandas分析和Pyecharts可视化等技术。关键词:Python爬虫、军事数据、异步爬取、反反爬、数据可视化。

2201_76125261的博客 1189

C++——string的模拟实现+详细讲解

函数返回一个指向字符串数组的常量指针,指向的字符可以用来读取字符串的内容,但不能修改。该函数的功能是将指定的字符串追加到当前字符串的末尾,并返回一个引用指向当前字符串对象。实现了字符串对象对字符的追加操作,通过这函数,可以将一个字符追加到字符串的末尾。在函数的实现中,首先通过assert语句进行断言验证,确保要访问的位置。函数比较两个内存块的内容,并返回一个整数作为比较的结果。的实现,其功能是返回字符串对象中存储的字符数量。表示当前字符串对象和参数字符串对象的大小。,即数组中位置为 pos 的字符的引用。

勇气是明知不可为而为之 533

鸿蒙开发实战项目(四十七):图片编辑(ArkTS)

本篇Codelab主要介绍如何基于图片编解码,实现图片编辑。图片的解码。使用PixelMap进行图片编辑,如裁剪、旋转、亮度、透明度、饱和度等。图片的编码。

斌擎科技 1586

史上最牛逼的导航网站(很全很详细)

今天,给大家推荐47个聚合型的导航网站 每一个都收录上百个网站,1个能顶100个,丝毫没有夸张的成分。 (推荐收藏) 设计师导航网站 01 优设导航 https://hao.uisdc.com/ 设计师必备的导航网站,包含设计工具、素材资源、字体设计、配色方案、酷站模板等。 界面清晰无广告,收录网站超过520个。 02 设计导航 http://h...

孙叫兽的博客 7万+

详解c++---string模拟实现

string主要函数的模拟实现。

qq_68695298的博客 1222

36、真核生物RNA PolII启动子预测相关研究

本文综述了真核生物RNA聚合酶II启动子预测的研究进展,涵盖转录调控机制、核心启动子元件(如TATA框、INR、GC框)、转录因子结合位点预测的挑战与方法。介绍了基于权重矩阵、神经网络和隐马尔可夫模型等多种启动子预测算法,并探讨了启动子分类策略及评分加权方法。通过Hertz-Stormo-Hartzell流程和基因微阵列分析实例,展示了如何识别保守调控序列。文章还总结了当前预测技术的局限性,提出了整合多组学数据、开发深度学习模型、加强实验验证等未来研究方向,旨在提升启动子识别的准确性与生物学意义。

palm99的专栏 187

C++【string类,模拟实现string类】

就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一块玩,则万事大吉,万一 不想分享就你争我夺,玩具损坏。可以采用深拷贝解决浅拷贝问题,即:每个对象都有一份独立的资源,不要和其他对象共享。父 母给每个孩子都买一份玩具,各自玩各自的就不会有问题了。

qq_67578580的博客 3698

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【C++】string类的模拟实现

本文围绕 C++ 中 string 类展开。首先介绍了 string 类的模拟实现,包括构造函数、浅拷贝与深拷贝问题,以及拷贝构造和赋值运算符重载的传统与现代写法。现代写法利用临时对象和自动析构特性,提高效率与资源利用率。还介绍了 string 类的其他接口如迭代器和各种操作函数等。接着说明了在 vs 和 g++ 下 string 的结构特点。此外提到了写时拷贝的概念及读取缺陷。最后给出了扩展阅读方向。

2401_82610555的博客 1963

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【C++驾轻就熟】string类以及string类的模拟实现

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 sring类的文档介绍总结:在使用string类时,必须包含#include头文件以及using namespace std; 2. string类对象的容量操作 注意:注意: 上面已经对string类进行了简单的介绍,大家只要能够正常使用即可。在面试中,面试官总喜欢让学

2201_75537851的博客 1182

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【C++】——string的模拟实现

在这里即一个一个字节的拷贝,动态申请资源时候如果浅拷贝会指向同一块资源,会有着程序崩溃的问题同一块空间析构了两次 程序崩溃深拷贝即调用拷贝构造,编译器生成的拷贝构造是浅拷贝,需要我们自己显示实现拷贝构造来进行深拷贝。

2402_82668782的博客 1526

【C++】模拟实现string类

对string类的模拟实现

dab112的博客 2084

C++《string的模拟实现》

通过学习string内的各个函数后我们可以发现在解决一些要使用到字符串的环境下有了string内的这些函数操作能大大简化,在此当中最主要的是在进行插入、删除等操作时我们不用再显示的去对字符串的内存空间进行调整。那么在之前我们只是了解了string的该如何使用,接下来在本篇当中我们将试着模拟实现string,我们在学习了string的使用之后要模拟实现是为了能从更底层来了解string的各个功能时如何实现的,这会让加深对string的了解。接下来就开始本篇的学习吧!

mljy.博客 3057

【C++初阶】第八站:string类的模拟实现

【C++初阶】第八站:string类的模拟实现,通用函数的模拟实现

weixin_65186652的博客 2103

C++ string类

目录 1. 为什么要学习string类 1.1 C语言中的字符串 1.2 两个面试题(暂不做讲解) 2. 标准库中的string类 2.1 string类(了解) 2.2 string类的常用接口说明(注意下面我只讲解最常用的接口) 1. string类对象的常见构造 2. string类对象的容量操作 3. string类对象的访问及遍历操作 4. string类对象的修改操作 5. string类非成员函数 6. 牛刀小试 3. string类的模拟实现 3.1 经...

m0_61548909的博客 9845

【C++之STL】摸清 string 的模拟实现(下)

7. 字符串操作 7. 1 `c_str()`和`date()` 7. 2 `find()` 8. 迭代器相关 8. 1 迭代器实现 8. 2 `begin()` 8. 3 `end()` 9. 运算符重载 9. 1 流插入和流提取 9. 2 比较运算符 10. `string`模拟实现的现代写法 11. 补充阅读:写时拷贝

fhvyxyci的博客 2662

【C++】string类的模拟实现(详解)

string类的模拟实现详解

2401_87820834的博客 1608

【C++】string类

C++ string类解析摘要 本文全面解析C++ string类,重点包括: string类解决了C语言字符串的4大痛点:安全性问题、内存管理复杂、功能有限、不符合面向对象思想 string类基础用法和C++11新特性(auto关键字和范围for循环) 详细介绍了5类核心接口: 构造函数(空字符串、C字符串构造等) 容量操作(size()/length()、resize()等) 元素访问和遍历(下标操作、迭代器、范围for) 通过代码示例演示string类的实际应用,包括字符串处理和安全操作 string

凤年徐的博客 3477

【C++】string类 模拟实现

本文详细介绍了C++中string类的模拟实现过程。首先在命名空间MyTest中定义string类,包含构造函数、析构函数、访问遍历、扩容、增删改查等核心功能。重点讲解了深浅拷贝的区别及现代写法注意事项,分析了不同编译器下string类的存储机制差异,并简要介绍了写时拷贝技术。文章通过具体代码示例展示了各个成员函数和非成员函数的实现细节,包括运算符重载、迭代器设计等,帮助读者深入理解string类的底层实现原理。最后指出不同平台下字符串存储方式的差异,为C++学习者提供了有价值的参考。

qjx的博客 1195
上一篇: 【C++】面试题:模拟实现string类(版本一:用深度拷贝来实现 )
下一篇: 【C++】模板类顺序表
pointer_y
博客等级 码龄11年 157粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值