C++--string的模拟实现

news2025/6/10 15:40:41

一,引言

string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。

二,默认成员函数

string主要有三个成员变量,字符串指针--用于存放数据,size--记录有效数据,capacity--记录内存的大小。

1,构造函数

负责对成员变量进行初始化操作,当不传参数时,顺序表中只有\0用于表示顺序表的结束。当传入参数时,将传入的参数存入string对象中。具体实现如下:

string( const char* str = "")
{
	_str = new char[strlen(str) + 1];
	_size = strlen(str);
	_capacity = strlen(str);
	strcpy(_str, str);
}

在进行开辟空间时多开了一个字节的空间,该字节的空间负责存放\0。

分别是无参调用,和带参调用。

2,拷贝构造函数

负责实现对象的深拷贝。为构造函数的一种。具体实现如下:

string(string& str)
{
	_str = new char[str._capacity + 1];
	_size = str._size;
	_capacity = str._capacity;
	strcpy(_str, str._str);
}

初始化逻辑与实现原理基本相同。strcpy函数用于字符串复制,包含两个参数:第一个参数是目标地址,第二个参数是源地址。该函数会将源地址处直到'\0'结束符的所有字符(包括'\0')复制到目标地址所在位置。

将s1是由s2拷贝构造而来的。

3,析构函数

释放已开辟的内存空间并将指针置空,同时将相关参数清零,具体实现如下:

~string()
{
	delete[]_str;
	_str = nullptr;
	_size = _capacity = 0;
}

s1被析构。

4,赋值重载

重载赋值运算符(=),将源对象内容完整复制到目标对象,实现对象间的深度赋值。

三,其他成员函数

1,c_str

返回string对象的字符数组成员的首地址。 具体实现如下:

char* c_str()
{
	return this->_str;
}

2,size

返回string对象中有效数据的个数。具体实现如下:

size_t size()const
{
	return this->_size;
}

 

 3,capacity

返回string对象中的容量不包括\0。具体实现如下:

size_t capacity() const
{
	return this->_capacity;
}

 

4,[]运算符重载

实现string对象某个字符的修改。具体实现如下:

char& operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}

返回的是该位置的引用可以对该对象的值进行修改。

对s1的第一个位置进行修改。

5,clear

清空对象内容,并将大小重置为0。具体实现如下:

void clear()
{
	_str[0] = '\0';
	_size = 0;
}

6.reserve

当对象内存不足时,该函数负责执行扩容操作。具体实现如下:

void string::reserve(size_t n)
{
	if (n > _capacity)
	{
		int com = _capacity == 0 ? n : _capacity * 2;
        if(com < n)
            {
                com = n;
            }
		char* ptr = new char[com + 1];
		strcpy(ptr, _str);
		delete[]_str;
		_str = ptr;
		ptr = nullptr;
		_capacity = com;

	}
}

当容量为零时,按需分配所需空间;若容量不为零,则比较当前需求与现有容量的两倍,取较大值以避免频繁扩容。注意,每次扩容时需额外预留一个字节用于存储字符串终止符'\0'。以下为测试用例演示:

int main()
{
	Cao::string s2("fdasjl");
	cout << s2.capacity() << endl;
	s2.reserve(10);
	cout << s2.capacity() << endl;
	Cao::string s1;
	cout << s1.capacity() << endl;
	s1.reserve(10);
	cout << s1.capacity() << endl;
	return 0;
}

7,push_back

尾插单个字符。具体实现如下:

void string::push_back(char ch)
{
	if (_size + 1 > _capacity)
	{
		reserve(_size + 1);
	}
	_str[_size] = ch;
	_size++;
	_str[_size] = '\0';
}

 先判断容量了,再进行插入。

8,append

尾插字符串。具体实现如下:

void string::append(const char* str)
{
	if (_size + strlen(str) > _capacity)
	{
		reserve(_size + strlen(str));
	}
	strcpy(_str + _size, str);
	_size = _size + strlen(str);

}

先进行容量判断,之后插入。

9,insert

在指定位置插入字符串,具体实现如下:

void string::insert(size_t pos, const char* str)
{
	if (_size + strlen(str) > _capacity)
	{
		reserve(_size + strlen(str));
	}
	strcpy(_str + pos + strlen(str), _str + pos);
	*this += str;
	_size += strlen(str);
}

先评估容量,再迁移数据腾出目标位置,最后插入字符串。

10,erase

指定位置,指定区域进行删除数据。具体实例如下:

void string::erase(size_t pos, size_t len )
{
	assert(pos < _size);
	if (pos + len >= _size)
	{
		_str[pos] = '\0';
		_size = _size - pos;
	}
	else
	{
		strcpy(_str + pos, _str + pos + len);
		_size = _size - len;
	}
}

分为两种情况,第一种指定长度之后还存在数据。第二种情况是,指定长度之后没有数据。

11,find

查找字符串,找到之后返回首个字符的下标。没有找到返回npos。具体实现如下:

size_t string::find(const char* str, size_t pos )
{
	assert(pos < _size);
	{
		char* ptr = _str + pos;
		return  strstr(ptr, str) - _str ;
	}
}

 

四,总结

关于函数的具体功能,可以参考string这篇文章。在练习过程中,不必追求完美实现,重点在于理解string的底层代码逻辑及其使用方法。

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

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

相关文章

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…

【若依】框架项目部署笔记

参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作&#xff1a; 压缩包下载&#xff1a;http://download.redis.io/releases 1. 上传压缩包&#xff0c;并进入压缩包所在目录&#xff0c;解压到目标…

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…