【C++】string的模拟实现

string的模拟实现

  • 1.string类的常用接口
    • [1.1 string类对象的常用构造](#1.1 string类对象的常用构造)
    • [1.2 string类对象的容量操作](#1.2 string类对象的容量操作)
    • [1.3 string类对象的访问及遍历操作](#1.3 string类对象的访问及遍历操作)
    • [1.4 string类对象的修改操作](#1.4 string类对象的修改操作)
    • [1.5 string类非成员函数](#1.5 string类非成员函数)
  • 2.模拟实现
    • [2.1 构造](#2.1 构造)
    • [2.2 容量](#2.2 容量)
    • [2.3 遍历操作](#2.3 遍历操作)
    • [2.4 修改操作](#2.4 修改操作)
    • [2.5 非成员函数](#2.5 非成员函数)
    • [2.6 swap和运算符重载](#2.6 swap和运算符重载)

1.string类的常用接口

1.1 string类对象的常用构造

(constructor)函数名称 功能说明
string() 构造空的string类对象,即空字符串
string(const char* s) 用C-string来构造string类对象
string(size_t n , char c) string类对象包含n个字符c
string(const string& s) 拷贝构造函数

1.2 string类对象的容量操作

函数名称 功能说明
size 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty 检测字符串释放为空串,是返回true,否则返回false
clear 清空有效字符
reserve 为字符串预留空间
resize 将有效字符串的个数改成n个,多出的空间用字符c填充

1.3 string类对象的访问及遍历操作

函数名称 功能说明
operator[] 返回pos位置的字符,const string类对象调用
begin + end beign获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend rbegin获取最后一个字符的迭代器 + rend获取第一个字符上一个位置的迭代器
范围for C++11支持更简洁的范围for的新遍历方式

1.4 string类对象的修改操作

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= 在字符串后追加字符串str
c_str 返回C格式字符串
find + npos 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,往后将其返回

1.5 string类非成员函数

函数名称 功能说明
operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>> 输入运算符重载
operator<< 输出运算符重载
getline 获取一行字符串
relational operators 大小比较

2.模拟实现

cpp 复制代码
#include<iostream>
#include <assert.h>
using namespace std;

class string
{
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

2.1 构造

cpp 复制代码
string()
{
	_str = new char[1] {'\0'};
	_size = 0;
	_capacity = 0;
}

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

string(size_t n, char c)
{
	_str = new char[n + 1];
	for(int i = 0;i<n;i++)
	{
		_str[i] = c;
	}
	_size = n;
	_str[n] = '\0';
}

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

其中string()和string(const char* s)这两个构造可以写成全缺省

cpp 复制代码
string(const char* s = "");//声明
string(const char* s)//定义,不用给缺省值
{
	_str = new char[strlen(s) + 1];
	_size = _capacity = strlen(s);
	strcpy(_str, s);
}

2.2 容量

cpp 复制代码
size_t size() const
{
	return _size;
}

size_t length() const
{
	return _size;
}

size_t capacity() const
{
	return _capacity;
}

bool empty()
{
	return _size == 0;
}

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

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

void resize(size_t n, char c)
{
	if (n > _size)
	{
		if (n > _capacity)
		{
			reserve(n+1);
		}
		for (size_t i = 0; i < n - _size; i++)
		{
			_str[i + _size] = c;
		}
		_size += n;
		_str[_size] = '\0';
	}
}

2.3 遍历操作

cpp 复制代码
char& operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}
	
typedef char* iterator;
typedef const char* const_iterator;
iterator :begin()
{
	return _str;
}
iterator end()
{
	return _str + size();
}
const_iterator begin() const
{
	return _str;
}
const_iterator end() const
{
	return _str + size();
}

2.4 修改操作

cpp 复制代码
void push_back(char ch)
{
	if (_capacity == _size)
	{
		size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
		reserve(newcapacity);
	}
	_str[_size] = ch;
	_str[_size + 1] = '\0';
	++_size;
}

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

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}
string& operator+=(const char* str)
{
	append(str);
	return *this;
}

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

//find实现两个,一个查找字符,一个查找字符串
size_t find(char ch, size_t pos)
{
	for (size_t i = pos; i < _size; i++)
	{
		if (_str[i] == ch)
		{
			return i;
		}
	}
	return npos;
}
size_t find(const char* sub, size_t pos)
{
	const char* p = strstr(_str + pos,  sub);
	return p - _str;
}

string substr(size_t pos, size_t len)
{
	if (len > _size - pos)
	{
		string sub(_str + pos);
		return sub;
	}
	else
	{
		string sub;
		sub.reserve(len);
		for (size_t i = 0; i < len; i++)
		{
			sub += _str[pos + i];
		}
		return sub;
	}
}

2.5 非成员函数

cpp 复制代码
//声明
istream& operator>>(istream& is, qbb::string& str);
ostream& operator<<(ostream& out, const string& s);

//定义
istream& operator>>(istream& is, string& str)
{
	str.clear();
	char buff[128];
	int i = 0;
	char ch = is.get();
	
	while (ch != ' ' && ch != '\n')
	{
		buff[i++] = ch;
		if (i == 127)
		{
			buff[i] = '\0';
			str += buff;
			i = 0;
		}
		ch = is.get();
	}
	if (i != 0)
	{
		buff[i] = '\0';
		str += buff;
	}
	return is;
}

ostream& operator<<(ostream& out, const string& s)
{
	for (auto ch : s)
	{
		out << ch;
	}
	return out;
}

2.6 swap和运算符重载

cpp 复制代码
void swap(string& s)
{
	std::swap(_str, s._str);//交换指针,本质是交换内置类型来达到string交换的效果
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}
string& operator+=(const char* str)
{
	append(str);
	return *this;
}
string& operator=(string tmp)
{
	swap(tmp);
	return *this;
}
bool operator<(const string& s) const
{
	return strcmp(_str, s._str) < 0;
}
bool operator<=(const string& s) const
{
	return *this < s || *this == s;
}
bool operator>(const string& s) const
{
	return (*this <= s);
}
bool operator>=(const string& s) const
{
	return !(*this < s);
}
bool operator==(const string& s) const
{
	return strcmp(_str, s._str) == 0;
}
bool operator!=(const string& s) const
{
	return !(*this == s);
}

欢迎捉虫~

相关推荐
Dxy12393102163 小时前
python如何使用nacos
开发语言·网络·python
玫瑰花店3 小时前
C++速通Lambda表达式
开发语言·c++
源码_V_saaskw3 小时前
JAVA校园跑腿校园外卖源码校园外卖小程序校园代买帮忙外卖源码社区外卖源码小程序+公众号+h5
java·开发语言·微信小程序·小程序
C嘎嘎嵌入式开发3 小时前
(20)100天python从入门到拿捏《JSON 数据解析》
开发语言·python·json
源码哥_博纳软云3 小时前
JAVA同城预约服务家政服务美容美发洗车保洁搬家维修家装系统源码小程序+公众号+h5
java·开发语言·微信小程序·小程序
snow@li3 小时前
d3.js:学习积累
开发语言·前端·javascript
编程岁月3 小时前
java面试-0203-java集合并发修改异常、快速/安全失败原理、解决方法?
java·开发语言·面试
CoderCodingNo4 小时前
【GESP】C++五级考试大纲知识点梳理, (3-4) 链表-双向循环链表
开发语言·c++·链表
llz_1124 小时前
第五周作业(JavaScript)
开发语言·前端·javascript