C++模拟实现常用的STL中string类

通过http://www.cplusplus.com/reference/这个网站可以查到一些C++库的使用方法,只是都是英文,是一个大的挑战
本文简单介绍下STL 中的string的基本操作

成员变量

private:
	char* _str;			//存放字符串
	size_t _size;		//当前有效字符串的数量
	size_t _capacity;	//能最大存储的有效字符串数量,不包括'\0'

	static size_t npos;
  • npos:代表着无符号数据的最大值,也就是[4294967295]

默认成员函数

构造函数

	//构造函数
	my_string(const char* str = "")
	{
		//防止传入的字符串就是空指针,strlen和strcpy不能访问空指针
		if(nullptr == str)
		{
			_size = 0;
			_str = nullptr;
		}
		else
		{
			_size = strlen(str);
			_str = new char[_capacity + 1];//预留'\0'的位置
			strcpy(_str, str);
		}
		_capacity = _size;
	}

析构函数

//析构函数
	~my_string()
	{
		delete[] _str;
		_str = nullptr;
		_size = _capacity = 0;
	}

拷贝构造

//拷贝构造
	my_string(const my_string& s)
	{
		/*
		//浅拷贝
		_str = s._str;
		_size = s._size;
		_capacity = s._size;
		*/

		//深拷贝
		_str = new char[s._size + 1];//多开一个
		strcpy(_str, s._str);
		_size = s._size;
		_capacity = s._size;
	}

运算符重载

赋值运算符

//赋值运算符重载
	my_string& operator=(const my_string& s)
	{
		if (this != &s)
		{
			delete[] _str;
			_str = new char[s._size + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}
		return *this;
	}

[ ]运算符重载

	//[]运算符重载
	char& operator[](size_t pos)
	{
		assert(pos < _size);//不能越界
		return _str[pos];
	}

+= 运算符重载

	my_string& operator+=(const my_string& s)
	{
		//如果空间不够,就扩容
		reserve(_size + s._size);
		strncpy(_str + _size, s._str, s._size + 1);//得要把末尾的'\0'也一起拷贝过来
		_size += s._size;
		return *this;
	}
	my_string& operator+=(const char* str)
	{
		size_t len = strlen(str);
		reserve(_size + len);
		strncpy(_str + _size, str, len + 1);//得要把末尾的'\0'也一起拷贝过来
		_size += len;
		return *this;
	}
	my_string& operator+=(const char s)
	{
		
		//如果空间不够,就扩容
		reserve(_size + 1);
		_str[_size++] = s;
		_str[_size] = '\0';
		return *this;
	}

cout运算符重载

在类的前面需要加友元,函数实现在类的外面

friend ostream& operator<<(ostream& out, const my_string& s);

ostream& operator<<(ostream& out, const my_string& s)
{
	cout << s._str << endl;
	return out;
}

cin运算符重载

在类的前面需要加友元,函数实现在类的外面

friend istream& operator>>(istream& in, my_string& s);

istream& operator>>(istream& in, my_string& s)
{
	//不能简单的使用cin,因为此时_str的空间不是new开辟出来的,在析构的时候会有问题
	while (1)
	{
		char ch = in.get();
		if (ch == ' ' || ch == '\n')
			break;
		s += ch;
	}
	return in;
}

getline 获取一行数据

在类的前面需要加友元,函数实现在类的外面

friend istream& getline(istream& in, my_string& s);

istream& getline(istream& in, my_string& s)
{
	while (1)
	{
		char ch = in.get();
		if (ch == '\n')
			break;
		s += ch;
	}
	return in;
}

比较运算符重载

	bool operator<(const my_string& s)
	{
		return strcmp(_str, s._str) < 0;
	}

	bool operator==(const my_string& s)
	{
		return strcmp(_str, s._str) == 0;
	}

	bool operator<=(const my_string& s)
	{
		return *this < s || *this == s;
	}

	bool operator>(const my_string& s)
	{
		return !(*this <= s);
	}

	bool operator>=(const my_string& s)
	{
		return !(*this < s);
	}

	bool operator!=(const my_string& s)
	{
		return !(*this == s);
	}

Modifiers修饰符

push_back 尾插

	void push_back(char c)
	{
		reserve(_size + 1);//判断是否满了
		_str[_size++] = c;
		_str[_size] = '\0';//记得结尾加'\0'
	}

append追加

	my_string& append(const my_string& s)//追加一个类
	{
		*this += s;
		return *this;
	}
	my_string& append(const char* c)//追加一个字符串
	{
		my_string s(c);
		*this += s;
		return *this;
	}
	my_string& append(const char c)//追加一个字符
	{
		this->append(c);
		return *this;
	}

insert 插入

	void insert(size_t pos, char c)//插入一个字符
	{
		assert(pos < _size);
		reserve(_size + 1);
		memmove(_str + pos + 1, _str + pos, _size - pos);
		_str[pos] = c;
		_size++;
		_str[_size] = '\0';
	}
	void insert(size_t pos, const char* str)//插入字符串
	{
		assert(pos < _size);
		int len = strlen(str);
		reserve(pos + _size);
		memmove(_str + pos + len, _str + pos, _size - pos);
		strncpy(_str + pos, str, len);//不能用strcpy,防止吧'\0'拷贝到中间位置
		_size += len;
		_str[_size] = '\0';
	}

erase 消除

void erase(size_t pos, size_t len = npos)
	{
		assert(pos < _size);

		if (_size - pos < len)//消除pos后面所有字符
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else//消除部分字符
		{
			memmove(_str + pos, _str + pos + len, _size - (pos + len));
			_size -= len;
			_str[_size] = '\0';
		}
	}

capacity 容量

size 返回字符串大小

	size_t size()
	{
		return _size;
	}

capacity 返回字符串容量

	size_t capacity()
	{
		return _capacity;
	}

reserve 增加容量

	void reserve(size_t n)
	{
		//如果n小于容量,则不做任何改变
		if (n > _capacity)
		{
			char* newstr = new char[n + 1];//预留'\0'的空间
			strcpy(newstr, _str);
			delete[] _str;
			_str = newstr;
			_capacity = n;
		}
	}

resize 固定容量

	void resize(size_t n, char c = '\0')
	{
		//n小于当前字段长度,进行删除
		if (n < _size)
		{
			_size = n;
			_str[_size] = '\0';
		}
		else //大于当前字段长度,进行插入
		{
			if (n > _capacity)//空间是否足够
				reserve(n);
			//插入
			for (size_t i = _size; i < n; i++)
				_str[i] = c;
			_size = n;
			_str[_size] = '\0';
		}
	}

clear 清理函数

	void clear()
	{
		_size = 0;
	}

empty 判空

	bool empty()const
	{
		return _size ? true : false;
	}

Iterators 迭代器

本质

typedef char* iterators;

begin

	iterators begin()
	{
		return _str;
	}

end

	iterators end()
	{
		return _str + _size;
	}

String operations

find 查找函数

size_t find(const char* str, size_t pos = 0)
	{
		const char* p = strstr(_str + pos, str);
		return (p == nullptr) ? npos : (p - _str);
	}

	size_t find(const my_string& s, size_t pos = 0)
	{
		return find(s._str, pos);
	}

	size_t find(const char& ch, size_t pos = 0)
	{
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == ch)
				return i;
		}
		return npos;
	}

substr 截取字符串

	my_string substr(size_t pos = 0, size_t len = npos)const
	{
		my_string ret("");
		for (size_t i = pos; i < len; i++)
		{
			ret += _str[i];
		}
		cout << ret << endl;
		return ret;
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值