string的模拟实现(String)

一、前言

在实现string类之前,我们需要知道string是表示字符串的字符串类 ,string类的成员变量如下(库中存在string类,所以命名为string会造成冲突,所以我们定义一个String类去实现string类的各种功能):

class String{
private:
	char* _str;        //字符串指针
	size_t _capacity;  //容量
	size_t _size;      //字符串大小
};

二、初始化与清理

2.1构造函数

	String(const char* str = "")
	{
		_size = strlen(str);
		_capacity = _size;
		_str = new char[_capacity + 1];  //申请连续空间
		strcpy(_str, str);     //拷贝字符串内容
	}

2.2析构函数

	~String(){
		if (_str){
			delete[] _str;
			_str = nullptr;        //空间置空
			_size = _capacity = 0; //容量大小都置0
		}
	}

2.3拷贝构造

	//1.一般写法
	String(const String& s){
		char *tmp = new char[s._capacity+1];
		strcpy(tmp, s._str);
		delete[] _str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
	}
	//2.现代写法
	String(const String& s)
		:_str(nullptr)
		, _size(s._size)
		, _capacity(s._capacity)
	{
		char* tmp(s._str); 
		swap(_str, tmp);
	}

2.4清除

	void clear(){
		char *tmp = new char[_capacity + 1];
		delete[] _str;
		tmp[0] = '\0';
		_str = tmp;
		_size = 0;
	}

三、运算符重载

3.1赋值运算符

	//一般写法
	String& operator=(const String &s){
		char *tmp = new char[s._capacity+1];
		strcpy(tmp, s._str);
		delete[] _str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
		return *this;
	}
	//现代写法
	String& operator=(String s){
		swap(_str, s._str);
		_size = s._size;
		_capacity = s._capacity;
		return *this;
	}

3.2其他运算符

	//<运算符
	bool operator<(const String& s){
		size_t i = _size;
		size_t c = s._size;
		if (i == 0 && c == 0){
			return false;
		}
		size_t num = 0;
		while (i&&c){
			if (_str[num] < s._str[num]){
				return true;
			}
			else if(_str[num]>s._str[num]){
				return false;
			}
			else{
				i--;
				c--;
				num++;
			}
		}
		if (i == 0&&c!=0){
			return true;
		}
		return false;
	}
	//==运算符
	bool operator==(const String& s){
		size_t i = _size;
		size_t c = s._size;
		int num = 0;
		while (i&&c){
			if (_str[num] != s._str[num]){
				return false;
			}
			i--;
			c--;
			num++;
		}
		if (c || i){
			return false;
		}
		return true;
	}
	//<=运算符
	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);
	}
	//!=运算符
	bool operator!=(const String& s){
		return !(*this == s);
	}
	//+=字符运算符
	String& operator+=(char c){
		PushBack(c); //尾插
		return *this;
	}
	//+=字符串运算符
	String& operator+=(const char* str){
		Append(str);   //尾插字符串
		return *this;
	}
	//[]运算符
	char& operator[](size_t index){
		return _str[index];
	}
	const char& operator[](size_t index)const{
		return _str[index];
	}

四、迭代器

4.1迭代器

	typedef char* iterator
	iterator begin(){
		return &_str[0];
	}
	iterator end(){
		return &_str[_size];
	}

4.2const迭代器

	typedef const char* const_iterator;
	const_iterator begin()const{
		return &_str[0];
	}
	const_iterator end()const{
		return &_str[_size];
	}

五、其他操作

5.1扩容

	//容量扩容
	void reserve(size_t newCapacity){
		if (newCapacity > _capacity){
			char *tmp = new char[newCapacity+1];
			strcpy(tmp, _str);
			swap(tmp, _str);
			_capacity = newCapacity;
		}
	}
	//大小扩容
	void resize(size_t newSize, char c = '\0'){
		if (newSize > _capacity){
			reserve(newSize);
		}
		if (newSize > _size){
			size_t num = _size;
			while (num != newSize){
				PushBack(c);
				num++;
			}
		}
		_size = newSize;
		_str[_size] = '\0';
	}

5.2插入,删除字符/字符串

	// 在pos位置上插入字符c/字符串str,并返回该字符的位置
	String& insert(size_t pos, char c){
		assert(pos < _capacity);
		if (_size >= _capacity){
			size_t newcapacity = _capacity == 0 ? 15 : 2 * _capacity;
			reserve(newcapacity);  //扩容
		}
		size_t it =_size;
		while (it != pos){
			_str[it] = _str[it-1];
			it--;
		}
		_str[pos] = c;
		_size++;
		_str[_size] = '\0';
		return *(this+pos);
	}
	String& insert(size_t pos, const char* str){
		assert(pos < _capacity);
		if (_size + strlen(str) >= _capacity){
			reserve(_size + strlen(str));
		}
		size_t l = strlen(str);
		size_t it = _size;
		while (it !=pos){
			_str[it + l-1] = _str[it-1];
			it--;
		}
		size_t p = pos;
		size_t i = 0;
		while (i < l){
			_str[p] = str[i];
			p++;
			i++;
		}
		_size += l;
		_str[_size] = '\0';
		return *(this+pos);
	}
	//尾插一个字符
	void PushBack(char c){
		if (_size >= _capacity){
			size_t newcapacity = _capacity == 0 ? 15 : 2 * _capacity;
			reserve(newcapacity);
		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	//尾插字符串
	void Append(const char* str){
		if (_size + strlen(str) >=_capacity){
			reserve(_size + strlen(str));
		}
		for (size_t i = 0; i < strlen(str); i++){
			PushBack(str[i]);
		}
	}
	//删除pos位置上的元素
	String& erase(size_t pos, size_t len){
		assert(pos + len < _capacity);
		size_t p = pos;
		while (p<_size-len){
			_str[p] = _str[p+len];
			p++;
		}
		_size-=len;
		_str[_size] = '\0';
		return *(this+pos);
	}

5.3查找

	//返回字符c在string中第一次出现的位置
	size_t find(char c, size_t pos = 0) const{
		while (pos<_size){
			if (_str[pos] == c){
				return pos;
			}
			pos++;
		}
		return -1;
	}
	//返回子串s在string中第一次出现的位置
	size_t find(const char* s, size_t pos = 0) const{
		size_t i = 0;
		while (pos < _size){
			size_t c_pos = pos;
			while(s[i]!='\0'&&_str[pos]!='\0'&&_str[pos] == s[i]){
				i++;
				pos++;
			}
			if (s[i] == '\0'){
				return c_pos;
			}
			if (_str[pos] == '\0'){
				return -1;
			}
			pos = c_pos+1;
			i = 0;
		}
		return -1;
	}

5.4判空,交换以及其他接口的实现

	//交换对象
	void Swap(String& s){
		swap(_str, s._str);
		int tmp = s._size;
		s._size = _size;
		_size = tmp;
		tmp = _capacity;
		_capacity = s._capacity;
		s._capacity = tmp;
	}
	//字符串首地址
	const char* c_str()const{
		return _str;
	}
	//大小
	size_t size()const{
		return _size;
	}
	//容量
	size_t capacity()const{
		return _capacity;
	}
	//判空
	bool empty()const{
		return _size == 0;
	}

5.5友元函数的输入输出

class String{
	friend ostream& operator<<(ostream& _cout, const String& s);
	friend istream& operator>>(istream& _cin, String& s);
	private:
		char* _str;        //字符串指针
		size_t _capacity;  //容量
		size_t _size;      //字符串大小
}
ostream& operator<<(ostream& _cout, const String& s){
	_cout << s._str;
	return _cout;
}
istream& operator>>(istream& _cin, String& s){
	_cin >> s._str;
	return _cin;
}

关于string的常用接口的实现基本结束,还有部分少见接口,读者可以自行实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值