C++--string类的模拟实现

string类的模拟实现

  • 定义私有成员变量,记录字符串的有效个数和容量。
private:
	char* _str; 
	size_t _size; //有效字符的个数
	size_t _capacity; //可以保存的最大有效字符个数  容量
	static const size_t npos;

1. 构造函数

	//全缺省构造
	String(const char* str = "")
	{
    
    
		_size = strlen(str);
		_str = new char[_size + 1];
		_capacity = _size;
		strcpy(_str, str);
	}
	String(const String& s)
		:_str(nullptr)
		, _size(0)
		, _capacity(0)
	{
    
    
		String tmp(s._str);
		Swap(tmp);
	}
	//交换函数
	void Swap(String& str)
	{
    
    
		swap(_str, str._str);
		swap(_size, str._size);
		swap(_capacity, str._capacity);
	}

2. 析构函数

	//析构
	~String()
	{
    
    
		if (_str)
		{
    
    
			delete[] _str;
			_str = nullptr;
		}
	}

3. 赋值运算符重载函数

	//赋值运算符
	String& operator=(const String &s)
	{
    
    
		if (this != &s)
		{
    
    
			String tmp(s);
			this->Swap(tmp);
		}
		return *this;
	}
	//运算符重载
	char& operator[](size_t index)
	{
    
    
		assert(index < _size);
		return _str[index];
	}
	const char& operator[](size_t index)const
	{
    
    
		assert(index < _size);
		return _str[index];
	}
	String& operator+=(const char* str)
	{
    
    
		append(str);
		return *this;
	}
	String& operator+=(const String& str)
	{
    
    
		this->append(str._str);
		return *this;
	}
	String& operator+=(char c)
	{
    
    
		push_back(c);
		return *this;
	}

4. 字符串的长度、容量,判空、清空

	// capacity
	size_t size()const
	{
    
    
		return _size;
	}
	size_t capacity()const
	{
    
    
		return _capacity;
	}
	bool empty()const
	{
    
    
		return _size == 0;
	}
	void clear()
	{
    
    
		_size = 0;
		_str[_size] = '\0';
	}
	//获取等效字符串
	const char* c_str()const
	{
    
    
		return _str;
	}

5. 迭代器(iterator)

  • 迭代器操作,类似于指针
  • 迭代器实现:字符指针
	// iterator
	iterator begin()
	{
    
    
		//第一个元素位置
		return _str; 
	}
	iterator end()
	{
    
    
		//最后一个元素的下一个位置
		return _str + _size;
	}
	const iterator begin()const
	{
    
    
		//第一个元素位置
		return _str;
	}
	const iterator end()const
	{
    
    
		//最后一个元素的下一个位置
		return _str + _size;
	}

6. 修改字符串长度、容量

	void resize(size_t n, char c = '\0')
	{
    
    
		//n>_capacity:增容
		if (n > _capacity)
		{
    
    
			reserve(n);
		}
		//_size < n <= _capacity
		//填充字符 c
		if (n > _size)
		{
    
    
			memset(_str + _size, c, (n - _size) * sizeof(char));
		}
		//直接修改size
		_size = n;
		_str[_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;
		}
	}

7. 字符串尾插、追加、插入、删除

	//尾插字符'c'
	void push_back(char c)
	{
    
    
		//检查空间
		if (_size == _capacity)
		{
    
    
			size_t newC = _capacity == 0 ? 15 : 2 * _capacity;
			//增容
			reserve(newC);
		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	//追加字符串
	void append(const char* str)
	{
    
    
		//检查容量
		int len = strlen(str);
		if (_size + len > _capacity)
		{
    
    
			reserve(_size + len);
		}
		//尾插  内存拷贝
		memcpy(_str + _size, str, sizeof(char)*len);
		//更新
		_size += len;
		_str[_size] = '\0';
	}
	// 在pos位置上插入字符c/字符串str,并返回该字符的位置
	String& insert(size_t pos, char c)
	{
    
    
		//检查位置
		assert(pos <= _size);
		//检查容量
		if (_size == _capacity)
		{
    
    
			size_t newC = _capacity = 0 ? 15 : 2 * _capacity;
			reserve(newC);
		}
		//移动元素,从后向前
		size_t end = _size + 1;
		while (end > pos)
		{
    
    
			_str[end] = _str[end - 1]; //第一次拷贝的就是\0
			--end;
		}
		//插入
		_str[pos] = c;
		//更新
		++_size;
		return *this;
	}
	String& insert(size_t pos, const char* str)
	{
    
    
		//检查位置
		assert(pos <= _size);
		//检查容量
		int len = strlen(str);
		if (_size + len > _capacity)
		{
    
    
			reserve(_size + len);
		}
		//移动元素  从后向前
		size_t end = _size + len;
		while (end > pos + len - 1)
		{
    
    
			_str[end] = _str[end - len];
			--end;
		}
		//插入
		memcpy(_str + pos, str, sizeof(char)*len);
		//更新
		_size += len;
		return *this;
	}
	// 删除pos位置上的元素,并返回该元素的下一个位置
	String& erase(size_t pos, size_t len)
	{
    
    
		//检查位置
		assert(pos < _size);
		if (pos + len >= _size)
		{
    
    
			_size = pos;
			_str[_size] = '\0';
		}
		else {
    
    
			//移动元素,从前向后
			size_t start = pos + len;
			for (; start <= _size; ++start)
			{
    
    
				_str[pos++] = _str[start];
			}
			_size -= len;
		}
		return *this;
	}

8. 字符串的比较

	bool operator<(const String& s)
	{
    
    
		int ret = strcmp(_str, s._str);
		if (ret < 0)
			return true;
		return false;
	}
	bool operator<=(const String& s)
	{
    
    
		return !(*this > s);
	}
	bool operator>(const String& s)
	{
    
    
		int ret = strcmp(_str, s._str);
		if (ret > 0)
			return true;
		return false;
	}
	bool operator>=(const String& s)
	{
    
    
		return !(*this < s);
	}
	bool operator==(const String& s)
	{
    
    
		int ret = strcmp(_str, s._str);
		if (ret == 0)
			return true;
		return false;
	}
	bool operator!=(const String& s)
	{
    
    
		return !(*this == s);
	}

9. 字符串查找

	// 返回c在string中第一次出现的位置
	size_t find(char c, size_t pos = 0) const
	{
    
    
		for (size_t i = 0; i < _size; ++i)
		{
    
    
			if (_str[i] == c)
			{
    
    
				return i;
			}
			return npos;
		}
	}
	// 返回子串s在string中第一次出现的位置
	size_t find(const char* s, size_t pos = 0) const
	{
    
    
		char* ptr = strstr(_str,s);
		if (ptr)
		{
    
    
			return ptr - _str;
		}
		return npos;
	}

猜你喜欢

转载自blog.csdn.net/qq_46659987/article/details/115018028