(C++)string模拟实现

string底层是一个是字符数组

为了跟库里的string区别,所以定义一个命名空间将类string包含

一、构造

1.构造函数

注意:将char*传给const char*是范围缩小,因此只能1:1构造一个

strlen遇到nullptr解引用会报错,因此缺省参数只能设置为" "

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

2.拷贝构造

深拷贝:重新开辟一个空间

浅拷贝(值拷贝):拷贝一个指针,指向同一片空间

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

3.析构

内置类型,调用默认成员函数,自定义类型调用默认构造

~string()
{
	if (_str != NULL)
	{
		delete[] _str;
		_str = NULL;
	}
	_size = 0;
	_capacity = 0;
}

4.赋值

赋值运算符也是默认成员函数,如果不写会进行浅拷贝/值拷贝

string& operator=(const string& s)
{
	_size = s._size;
	_capacity = s._capacity;
	delete[] _str;
	_str = new char[_capacity+1];
	strcpy(_str, s._str);
	return *this;
}

二、迭代器

使用typedef 将用iterator代替char*

1.begin

iterator begin()
{
	return _str;
}

2.end

iterator end()
{
	return _str + _size;
}

三、修改

1.push_back

void push_back(char c)
{
	if (_size + 1 > _capacity)
	{
		reserve(_size + 1);
		char* tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
	}
	_str[_size] = c;
	_size++;
	_str[_size] = '\0';
}

2.+=

复用尾插

string& operator+=(char c)
{
	push_back(c);
	return *this;
}

3.append

通过reserve类似扩容的操作,扩大了字符串长度的空间,并且在原字符串‘\0’的位置上拷贝str字符串

void append(const char* str)
{
	size_t len = strlen(str);
	if (len + _size > _capacity)
	{
		reserve(len + _size);
		char* tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
	}
	strcpy(_str + _size, str);
	_size += len;
}

4.clear

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

5.swap

void swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
void swap(string& s)
{
	bit::swap<char*>(_str, s._str);
	bit::swap<size_t>(_size, s._size);
	bit::swap<size_t>(_capacity, s._capacity);
}

6.c_str

const char* c_str()const
{
	const char* tmp = _str;
	return tmp;
}

四、容量

1.size

	size_t size()const
	{
		return _size;
	}

2.capacity

size_t capacity()const
{
	return _capacity;
}

3.empty

bool empty()const
{
	if (_size == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

4.resize

分三种情况

n<_size  删除数据

_size<n<_capacity 剩余空间初始化

n>_capacity 扩容+初始化

void resize(size_t n, char c = '\0')
{
	if (n <= _size)
	{
		_size = n;
		_str[n] = '\0';
	}
	else
	{
		reserve(n);
		size_t i = _size;

		while (i < n)
		{
			_str[i] = c;
			i++;
		}
		_size = n;
		_str[_size] = '\0';
	}
}

5.reserve

为防止new失败,所以使用临时变量tmp指向new出来的空间,若new成功,释放旧空间,并将—_str指向新的空间

void reserve(size_t n)
{
	if (n > _capacity)
	{
		_capacity = n;
		char* tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		delete[]_str;
		_str = tmp;
	}
}

五、访问

1.[ ]

char& operator[](size_t index)
{
	return _str[index];
}
const char& operator[](size_t index)const
{
	return _str[index];
}

2."<,<=,>,>=,==,!="

通过strcmp,比较字符串从头开始字符的ASCII值,再通过复用来实现剩下的

const只能调用const,非const既可以调用非const,也可以调用const

bool operator<(const string& s)
{
	return (*this >= s);
}
bool operator<=(const string& s)
{
	return !(*this > s);
}
bool operator>(const string& s)
{
	return (strcmp(_str, s._str) > 0);
}
bool operator>=(const string& s)
{
	return (*this == s || *this > s);
}
bool operator==(const string& s)
{
	return strcmp(_str, s._str) == 0;
}
bool operator!=(const string& s)
{
	return !(*this==s);
}

3.find

size_t find(char c, size_t pos = 0)const
{
	while (pos < _size)
	{
		if (_str[pos] == c)
		{
			return pos;
		}
		pos++;
	}
	return npos;
}
size_t find(const char* s, size_t pos = 0)const
{
	const char* p = strstr(_str, s);
	if (p != nullptr)
	{
		return _str - p;
	}
	return npos;
}

4.insert

注意size_t类型变量没有负数

string& insert(size_t pos, char c)
{
	if (_size + 1 > _capacity)
	{
		reserve(_size + 1);
		char* tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		delete[]_str;
		_str = tmp;
	}
	size_t end = _size;
	while (end >= pos)
	{
		_str[end + 1] = _str[end];;
		end--;
	}
	_str[pos] = c;
	_size++;
	_str[_size] = '\0';
	return *this;
}
string& insert(size_t pos, const char* str)
{
	size_t len = strlen(str);
	if (_size + len > _capacity)
	{
		reserve(_size + len);
		char* tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		delete[]_str;
		_str = tmp;
	}
	size_t end = _size;
	while (end >= pos)
	{
		_str[end + len] = _str[end];
		end--;
	}
	strncpy(_str + pos, str, len);
	_size += len;
	return *this;
}

5.erase

pos位置开始删除len个数据

string& erase(size_t pos, size_t len)
{
	if (len == npos && len + pos > _size)
	{
		_str[pos] = '\0';
	}
	else
	{
		while (pos+len<_size)
		{
			_str[pos] = _str[pos + len];
			pos++;
		}
		_size -= len;
		_str[_size] = '\0';
	}
	return *this;
}

6.流插入<<

ostream& operator<<(ostream& _cout, const bit::string& s)
{
	for (int i = 0; i < s._size; i++)
	{
		_cout << s[i] << "";
	}
	_cout << endl;
	return _cout;
}

7.流提取>>

输入多个值,C++规定 空格/换行是值与值之间的区分

istream& operator>>(istream& _cin, bit::string& s)
{
	s.clear();
	char ch = _cin.get();
	char buf[128];
	int index = 0;
	while (ch != ' ' && ch != '\n')
	{
		buf[index++] = ch;
		if (index == 127)
		{
			buf[index] = '\0';
			s += buf;
			index = 0;
		}
		ch = _cin.get();
	}
	if (index != 0)
	{
		s += buf;
	}
	return _cin;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes入门-大简介

目录 何为微服务 何为云原生 何为编排器 “Kubernetes”这个名字来自希腊语&#xff0c;意思是“舵手”舵手是一个航海/航行术语&#xff0c;指掌舵的人从本质上说&#xff0c;Kubernetes是云原生微服务(cloud-native microservice)应用的编排器(orchestrator) 何为微服务 …

力扣刷题--728. 自除数【简单】

题目描述 自除数 是指可以被它包含的每一位数整除的数。 例如&#xff0c;128 是一个 自除数 &#xff0c;因为 128 % 1 0&#xff0c;128 % 2 0&#xff0c;128 % 8 0。 自除数 不允许包含 0 。 给定两个整数 left 和 right &#xff0c;返回一个列表&#xff0c;列表的…

安利一款非常不错浏览器文本翻译插件(效果很不错,值得一试)

官网地址&#xff1a;https://immersivetranslate.com/ “沉浸式翻译”这个词&#xff0c;由我们发明创造。如今&#xff0c;它已然成为“双语对照翻译”的代名词。自2023年上线以来&#xff0c;这款备受赞誉的 AI 双语对照网页翻译扩展&#xff0c;已帮助超过 100 万用户跨越语…

USB (3)

USB 流控 USB是polled bus,这和PCIe不一样,所有的transfer都是由host发起的。 对于IN(从device到host)。 如果device没有数据,那么只能回复NAK。 Token received corrupted

2024年高考作文考人工智能,人工智能写作文能否得高分

前言 众所周知&#xff0c;今年全国一卷考的是人工智能&#xff0c;那么&#xff0c;我们来测试一下&#xff0c;国内几家厉害的人工智能他们的作答情况&#xff0c;以及能取得多少高分呢。由于篇幅有限&#xff0c;我这里只测试一个高考真题&#xff0c;我们这里用百度的文心…

MySQL事务,视图,用户管理学习笔记【事务概念 | 事务隔离级别 | 设置级别 | 视图 | 用户管理】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;事务初…

109.网络游戏逆向分析与漏洞攻防-装备系统数据分析-商店与捨取窗口数据的处理

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 现在的代码都是依据数据包来写的&#xff0c;如果看不懂代码&#xff0c;就说明没看懂数据包…

使用 Scapy 库编写 TCP ACK 洪水攻击脚本

一、介绍 TCP ACK洪水攻击是一种分布式拒绝服务攻击&#xff08;DDoS&#xff09;&#xff0c;攻击者通过向目标服务器发送大量伪造的TCP ACK&#xff08;确认&#xff09;数据包&#xff0c;使目标服务器不堪重负&#xff0c;无法正常处理合法请求。虽然ACK包通常用于确认接收…

【上海大学计算机组成原理实验报告】七、程序转移机制

一、实验目的 学习实现程序转移的硬件机制。 掌握堆栈寄存器的使用。 二、实验原理 根据实验指导书的相关内容&#xff0c;实验箱系统的程序转移硬件机制在于&#xff0c;当LDPC有效时&#xff0c;如果此时DUBS上的值就是转移的目标地址&#xff0c;则此目标地址被打入PC&am…

【数据分析基础】实验三 文件操作、数组与矩阵运算

一&#xff0e;实验目的 掌握上下文管理语句with的使用方法。掌握文本文件的操作方法。了解os、os.path模块的使用。掌握扩展库Python-docx、openpyxl的安装与操作word、Excel文件内容的方法。熟练掌握numpy数组相关运算和简单应用。熟练使用numpy创建矩阵&#xff0c;熟悉常用…

Python | Leetcode Python题解之第135题分发糖果

题目&#xff1a; 题解&#xff1a; class Solution:def candy(self, ratings: List[int]) -> int:n len(ratings)ret 1inc, dec, pre 1, 0, 1for i in range(1, n):if ratings[i] > ratings[i - 1]:dec 0pre (1 if ratings[i] ratings[i - 1] else pre 1)ret p…

27-LINUX--I/O复用-poll

一.poll概述 poll是一个多路复用的I/O模型&#xff0c;一个进程监视多个文件描述符&#xff0c;当文件描述符就绪时&#xff0c;poll返回可读并做相应处理。 1.poll的模型 #include <poll.h>struct pollfd {int fd; //文件描述符short events; //事件类型 s…

codesys【CAN总线】

1下载设备描述文件&#xff1a; 必须下载设备描述文件&#xff0c;要不然编程软件无法正确组态。 根据实际设备【品牌】去官网搜索下载。 以 DMA882-CAN 为例 CAN的设备描述文件是【.eds】的扩展名 安装设备描述文件。 2添加CAN总线&#xff1a; 1添加【CAN总线】&#xff1a…

Chroium 源码目录结构分析(1):源码目录体积一栏

获取源码 首先&#xff0c;我们拉一份最新的源代码&#xff08;笔者是2024.6.6日拉取的&#xff09;&#xff1a; fetch --nohistory chromium 源码预处理 如果运行build&#xff0c;会生成许多生成的代码&#xff0c;因此我们不运行build。 然后&#xff0c;把干扰后续分析…

Map深度学习

Map Map是一个键值对的集合&#xff0c;和object类似&#xff0c;Map作为构造函数&#xff0c;可以通过全局对象获取到。需要通过new操作创建实例对象&#xff0c;直接调用会报错。Map构造函数接受一个iterable类型的函数&#xff0c;用来初始化Map。 var m new Map([[1, &qu…

centos7安装字体

1.安装命令 yum install fontconfig #字体库命令 yum install mkfontscale #更新字体命令2.安装字体&#xff08;注意权限问题&#xff09; 进入目录 /usr/share/fonts &#xff0c;该目录是 centos7 字体库的默认安装目录。在该目录下创建一个文件夹 ekp &#xff08;名字…

理解我的积木编程思想

1 学习教程&#xff0c;至少7139手册2 编程实践&#xff0c;遇到实际问题后&#xff0c;在技术资料中查找关键词3 选择适合的条目找到代 码。修正&#xff0c;组合。

封装了一个简单理解的iOS竖直文字轮播

效果图 原理 就是持有两个视图&#xff0c;并且两个视图同时改变origin.y 动画结束之后&#xff0c;判断哪个视图是在上面并且看不到的&#xff0c; 则将该视图移动到底部&#xff0c;并且该视图展示下一跳内容 在开始下一轮动画 代码 - (void)startAnimationWithDuration:(…

若依项目部署(Linux2.0)

解压jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 配置Java环境变量&#xff1a; vim /etc/profile export JAVA_HOME/root/soft/jdk1.8.0_151 export JRE_HOME${JAVA_HOME}/jre export CLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH${JAVA_HOME}/bin:$PATH 设置环境…

WordPress 高级缓存插件 W3 Total Cache Pro 详细配置教程

说起来有关 WordPress 缓存插件明月已经发表过不少文章了,但有关 W3 Total Cache Pro 这个 WordPress 高级缓存插件除了早期【网站缓存插件 W3 Total Cache,适合自己的才是最好的!】一文后就很少再提及了,最近因为明月另一个网站【玉满斋】因为某些性能上的需要准备更换缓存…