模拟实现string类

 

#pragma once
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;
namespace dream
{
	class string
	{
	public:

		//string()     //没必要,直接写一个全缺省
		//	:_size(0),
		//	_capacity(0),
		//	_str(nullptr)
		//{}

		typedef char* iterator;
		//构造函数
		string( const char* ps="")
			:_size(strlen(ps)),
			_capacity(strlen(ps)+16)//初始化,如果空开辟16个空间,如果字符串创建,那就字符串长度+16
		{
			_str = new char[strlen(ps)+17];
			strcpy(_str, ps);
			//cout << "test" << endl; //用来测试构造函数是否成功
		}

		//拷贝构造
		string( const string& s)
		{//实现深拷贝
			_size = s._size;
			_capacity = s._capacity;
			_str = new char[_capacity + 1];
			strcpy(_str, s._str);
		}
		//赋值重载
		string& operator=(const string& s)
		{//这不就跟深拷贝一样的么
			_size = s._size;
			_capacity = s._capacity;
			_str = new char[_capacity + 1];
			strcpy(_str, s._str);
			return *this;
		}

		//求当前string字符串大小
		const size_t size()
		{
			return _size;
		}
		//求字符串容量
		const size_t capacity()
		{
			return _capacity;
		}
		//返回_str的地址
		const char* get_c()
		{
			return _str;
		}
		//求当前string字符串长度
		const size_t length()
		{
			return size_t();
		}
		//析构函数
		~string()
		{
			_size = _capacity = 0;
			delete[] _str;
			cout << "test_析构函数" << endl;
		}
		//重载【】符号
		char& operator[](size_t pos)
		{//实现这个基本上就能实现遍历了
			return _str[pos];
		}
		//实现简单的迭代器
		iterator begin()
		{//头
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		//尾插
		const string& push_back(char ch)
		{
			if (_size >= _capacity)
			{
				reserve(_capacity * 2);
			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
			return *this;
		}
		//扩容函数
		void reserve(size_t n)
		{//如果扩容函数给的n比_capacity小那就什么都不做,这个条件判断非常重要,不然就会出现bug了
			if (n <= _capacity)
				return;
			else
			{//n大于capacity那就扩容
				char* tem = new char[n + 1];
				strcpy(tem, _str);
				delete[] _str;	//释放原空间
				_str = tem;     //找到新地址
				_capacity = n;  //更改容量
			}
		}
		//扩容函数 resize()
		void resize(size_t n,char ch='\0')
		{//半缺省,这样就能实现不传参默认填充\0
			if (n <= _size)	
			{//缩容是有代价的
				_str[n] = '\0';
				n++;  //当n过小的时候本质上就是保留前n个
				_size = n;
			}
			else if (_size< n <= _capacity)
			{
				return;
			}
			else
			{
				char* tem = new char[n + 1];
				strcpy(tem, _str);
				delete[] _str;	//释放原空间
				_str = tem;     //找到新地址
				_capacity = n;  //更改容量
				while (_size < _capacity)
				{
					_str[_size] = ch;
					_size++;
				}
				//最后一个位置用来放\0
				_str[_size] = '\0';
			}
		}
		//头插字符
		const string& insert(size_t pos, const char ch)
		{//断言
			assert(pos <= _size);
			if (_size + 1 > _capacity)
			{
				reserve(2 * _capacity);
			}
			size_t end = _size+1;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_size++;
			return *this;
		}
		//头插字符串
		const string& insert(size_t pos, const char* str)
		{//复用头插字符函数
			assert(pos <= _size);
			int len = strlen(str);
			while (len >= 1)
			{//把字符串的每一个字符都拿来头插
				insert(pos, *(str + len - 1));
				len--;
			}
			return *this;
		}
		//截取字符串功能
		char* substr(size_t pos, size_t n)
		{
			char* ret = new char[n + 1];
			strncpy(ret, _str+pos,n);
			ret[n] = '\0';
			return ret; //成功实现
		}

		//删除功能

	private:
		 char*  _str;
		size_t _size;
		size_t _capacity;
	};
	//流插入重载
	ostream& operator<<(ostream& out, dream::string& s)
	{
		size_t i = 0;
		for (auto ch : s)
		{
			out << ch;
		}
		return out;
	}

	流提取重载
	//istream& operator>>(istream& in, dream::string& s)
	//{
	//	char ch;
	//	in >> ch;
	//	std::cin.get();
	//	while (ch != ' ' || ch != '\n')
	//	{
	//		s.push_back(ch);
	//		in >> ch;
	//		if (ch == ' ' || ch == '\n')
	//			break;
	//	}//目前这种写法会陷入死循环
	//	return in;
	//}
	istream& operator>>(istream& in, dream::string& s)
	{
			char ch;
			ch = in.get();
	while (ch != ' ' || ch != '\n')
	{
		s.push_back(ch);
		ch = in.get();//输入一个字符就给string插入一个字符
		if (ch == ' ' || ch == '\n')
			break;
	}//这样就好了,如果你删除==空格的判断条件就等于实现了getline
		return in;
	}
}

这是我的gitee链接:

cplusplus: c++学习的代码仓库

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值