模拟实现string类

目的:通过模拟实现库里的string(只实现核心,或常用的功能) ,加深对其理解

在代码中已给较多注释。相信看懂已经没有什么难度。

这里便不再给出。有疑问可私信或评论

namespace my_string
{
	class string
	{

		typedef char* iterator;
		typedef const char* const_iterator;//string类并不常用迭代器,库是为了保存与其他容器的一致性



	public:


		//给具有const属性的使用
		iterator begin()const 
		{
			return _str;
		}
		iterator end()const
		{
			return _str + _size;
		}


		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + size();
		}




		//string()
		//	:_str("")
		//	, _size(0)
		//	, _capacity(0)
		//{}

		//string的初始化
		//因为string是管理字符串的。
		//在不考虑传string类的情况下
		//初始化无非就两种情况
		//1.无参  2.传一个字符串


		//给一个缺省值为""的缺省参数str
		//这样我们就可以对上面两种情况进行同一处理
		string(const char* str = "")//加不加const 取决于是否要修改传进来的内存数据
			:_str(nullptr)
			, _size(strlen(str))
			, _capacity(_size)
		{
			_str = new char[_capacity + 1]; //+1是给‘\0’准备的
			strcpy(_str, str);
		}

		//下面处理传string类的情况,也就是同类型拷贝
		string(const string& s)
			:_str(nullptr)
			, _size(0)
		{
			string tmp(s._str);//这样可以不用自己写拷贝。创建一个string ,再把他指向的内存空间交换即可
			swap(tmp);
		}
		
		~string()
		{
			delete[]_str;
			_capacity = 0;
			_size = 0;
		}


		//返回值是引用是为了可以多次赋值
		string& operator=(string s)//不传引用是为了在传参的时候直接拷贝构造一次
		{
			swap(s);//仿造上面拷贝构造的写法
			return *this;
		}




		//增删查改

		//实现insert 以便复用

		string& insert(size_t pos, char x)//单个字符    在pos位置插入字符x,则之后的数据均往后移
		{

			//插入之前要先考虑容量是否足够。因此先调用reserve确保容量足够

			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : 2 * _capacity);
			}


			//从pos开始往后的位置均往后移,为pos腾出空位
			int end = size();
			while (end != pos - 1)//-1是因为pos位置上的元素也要往后移动
			{
				_str[end+1] = _str[end];
				end--;
			}
			_str[pos] = x;
			_size++;

			return *this;

		}
		string& insert(size_t pos, char*str)//在pos位置插入一个字符串。则之后的数据往后移动
		{
			//可以仿造上面的思路,往后移出足够的空间,再放入。
			//也可以直接复用上面的insert.这里偷个懒选第2个
			int len = strlen(str)-1;//-1是为了去掉'\0'
			while (len >= 0)
			{
				//注意是从后往前插入
				insert(pos, *(str + len));
				len--;

			}

			return *this;

		}

		void push_back(const char& x)//一个字符插入 库里面有,我们可以跟着实现一个
		{
			//if (_size == _capacity)
			//{
			//	reserve(_capacity == 0 ? 4 : 2 * _capacity);
			//}
			//_str[_size] = x;
			//_size++;
			//_str[_size] = '\0';

			insert(size(), x);//直接复用即可 要学会摸鱼偷懒
		}

		string& operator+=(char c)//相当于在尾部+=一个字符
		{
			insert(size(), c);
		}

		string& operator+=(char* str)//处理上面+=一个字符字符串的情况
		{
			insert(size(), str);
		}

		//删除
		string& erase(size_t pos=0, size_t len=npos)//从pos位置开始往后删除len个字符
		{
			assert(pos < size());


			if (len == npos || pos + len >= size())//如果往后删的长度超过或等于\0,则在pos位置放个\0即可
			{

				_size = pos;
				_str[_size] = '\0';
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}


			return *this;
		}

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

		}
		
		//查

		size_t find(char ch)//找单个字符
		{
			for (size_t i = 0; i < size(); i++)
			{
				if (ch == _str[i])
				{
					return i;
				}
			}


			return npos;
		}

		size_t find(char *s, size_t pos = 0)//从pos位置开始找跟s相同的字串
		{
			char *tmp = strstr(_str + pos, s);

			if (tmp == nullptr)
			{
				return npos;
			}
			else
			{
				return tmp - _str;

			}

		}



		//string类的比较,实现两个。其他复用

		bool operator<(const string& s)
		{
			if (strcmp(_str, s._str)<0)
			{
				return true;
			}
			else
			{
				return false;
			}

		}

		bool operator==(const string& s)
		{
			if (strcmp(_str, s._str) == 0)
			{
				return true;
			}
			else
			{
				return false;
			}

		}

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

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

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

		char& operator[](size_t i)
		{
			assert(i >= 0);
			return _str[i];
		}


		void resize(size_t n,char ch='\0')//重置容器大小
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{

				if (n > _capacity)
				{
					reserve(n);
				}
				memset(_str + _size, ch, n - _size);

				_size = n;
				_str[_size] = '\0';

			}


		}


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

				for (size_t i = 0; i <= size(); i++)
				{
					tmp[i] = _str[i];

				}

				delete[]_str;

				_str = tmp;
				_capacity = n;


			}


		}

		size_t size()
		{
			return _size;
		}

		size_t capacity()
		{
			return _capacity;
		}

		void swap(string& tmp)
		{
			std::swap(_str,tmp._str);
			std::swap(_size, tmp._size);
			std::swap(_capacity, tmp._capacity);
		}


	private:

		char*_str;
		size_t _size;
		size_t _capacity;
		
		
		static const size_t npos;

	};
	
	const size_t string::npos = -1;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值