【c++】string类模拟实现

目录

 

string有什么用?

string类的使用

模拟实现string类


string有什么用?

    C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,比如strstr, strcpy,

strcmp, strcat等等, 但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理. 相比较来

说c++中的string类是非常好用的.

string类的使用

我们给一组简单的测试:

void test()
{
	string s("hello");
	string s1(", the weather is fine!");

	string::iterator sit = s.begin();
	while (sit != s.end())
	{
		cout << *sit;
		++sit;
	}
	cout << endl;

	s.append(" world");
	cout << s << endl;

	s += s1;
	cout << s << endl;

	s.insert(13, "my name is qujiale, ");
	cout << s << endl;

	cout << s.size() << endl;
}

运行结果:

模拟实现string类

  我们给出代码并且将上面的测试在下面也进行测试

#include <iostream>
#include <assert.h>
using namespace std;

char* StrStr(char* dest, char* src)
{
	char* pdest = dest;
	char* psrc = src;
	while (*pdest)
	{
		if (*pdest == *psrc)
		{
			char* mdest = pdest;
			char* msrc = psrc;
			while (*mdest && *msrc)
			{
				if (*mdest != *msrc)
					break;
				mdest++;
				msrc++;
			}
			if (*msrc == '\0')
				return pdest;
		}
		++pdest;
	}
	return nullptr;
}

class String
{
public:
	typedef char* iterator;
	typedef const char* const_iterator;
public:
	String(char* str = "")
	{
		if (str == NULL)
		{
			return;
		}
		_size = strlen(str);
		_str = new char[_size + 1];
		strcpy(_str, str);
		_capacity = _size;
	}

	void Swap(String& s)
	{
		swap(_str, s._str);
		swap(_size, s._size);
		swap(_capacity, s._capacity);
	}

	//深拷贝
	//浅拷贝: 会导致同一资源释放两次
	String(const String& s)
		: _str(nullptr)
		, _size(0)
		, _capacity(0)
	{
		String tmp(s._str);
		Swap(tmp);
	}

	//调用交换函数
	String& operator=(String s)
	{
		if (this != &s)
		{
			Swap(s);
		}
		return *this;
	}

	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}
	}

	//迭代器
	iterator begin()
	{
		return _str;
	}

	iterator end()
	{
		return _str + _size;
	}

	const_iterator begin() const
	{
		return _str;
	}

	const_iterator end() const
	{
		return _str + _size;
	}

	const_iterator cbegin() const
	{
		return _str;
	}

	const_iterator cend() const
	{
		return _str + _size;
	}

	//插入删除
	void PushBack(char c)
	{
		//判断容量
		if (_size == _capacity)
		{
			size_t newC = _capacity == 0 ? 15 : 2 * _capacity;
			Reserve(newC);
		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}

	void Append(size_t n, char c)
	{
		for (size_t i = 0; i < n; i++)
		{
			PushBack(c);
		}
	}

	void Append(const char* str)
	{
		size_t sz = strlen(str);
		if (_size + sz > _capacity)
		{
			Reserve(_size + sz);
		}
		//从\0位置开始拷贝
		strcpy(_str + _size, str);
		_size += sz;
	}

	String& operator+=(char c)
	{
		PushBack(c);
		return *this;
	}

	String& operator+=(const char* str)
	{
		Append(str);
		return *this;
	}

	String& operator+=(const String& str)
	{
		Append(str._str);
		return *this;
	}

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

	//容量
	size_t Size() const
	{
		return _size;
	}

	size_t Capacity() const
	{
		return _capacity;
	}

	bool Empty() const
	{
		return _size == 0;
	}

	void Resize(size_t n, char c = '\0')
	{
		if (n > _size)
		{
			if (n > _capacity)
			{
				Reserve(n);
			}
			memset(_str + _size, c, n - _size);
		}
		_size = n;
		_str[_size] = '\0';
	}

	void Reserve(size_t n)
	{
		//开空间, 将原有数据进行拷贝, 释放原有空间, 更新capacity
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			if (_str)
			{
				strcpy(tmp, _str);
				delete[] _str;
			}
			_str = tmp;
			_capacity = n;
		}
	}

	//非const : 可读可写
	char& operator[](size_t index)
	{
		assert(index < _size);
		return _str[index];
	}

	//const 对象: 只读接口
	const char& operator[](size_t index) const
	{
		assert(index < _size);
		return _str[index];
	}

	const char* c_str() const
	{
		return _str;	
	}

	size_t Find(char c, size_t pos = 0)
	{
		for (size_t i = pos; i < _size; i++)
		{
			if (c == _str[i])
				return i;
		}
		return npos;
	}

	size_t Find(char* s, size_t pos = 0)
	{
		char* start = StrStr(_str + pos, s);
		if (start == nullptr)
			return npos;
		else
			return start - _str;
	}

	void Insert(size_t pos, char c)
	{
		assert(pos <= _size);
		if (_size == _capacity)
		{
			size_t newC = _capacity == 0 ? 15 : 2 * _capacity;
			Reserve(newC);
		}

		//移动元素, 包括'\0'
		size_t end = _size + 1;
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			--end;
		}

		//插入
		_str[pos] = c;
		++_size;
	}

	void Insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		size_t sz = strlen(str);
		if (sz + _size > _capacity)
		{
			Reserve(sz + _size);
		}

		size_t end = _size + sz;
		while (end > pos + sz - 1)
		{
			_str[end] = _str[end - sz];
			--end;
		}
		
		int i = 0;
		while (*str)
		{
			_str[pos + i] = *str++;
			++i;
		}

		_size += sz;
	}

	void Erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		//不够删
		if (pos + len >= _size)
		{
			_size = pos;
			_str[_size] = '\0';
			return;
		}
		size_t start = pos + len;
		while (start <= _size)
		{
			_str[start - len] = _str[start];
			++start;
		}

		_size -= len;
	}

	void Erase(iterator it)
	{
		assert(it < end() && it >= begin());
		while (it != end())
		{
			*it = *(it + 1);
			++it;
		}
		--_size;
	}

private:
	friend ostream& operator<<(ostream& _cout, const String& s);
private:
	static const size_t npos;
	char* _str;
	size_t _size;
	size_t _capacity;
};
const size_t String::npos = -1;
ostream& operator<<(ostream& _cout, const String& s)
{
	for (const auto& ch : s)
	{
		cout << ch;
	}
	return _cout;
}

void test()
{
	String s("hello");
	String s1(", the weather is fine!, this is realize.cpp");

	String::iterator sit = s.begin();
	while (sit != s.end())
	{
		cout << *sit;
		++sit;
	}
	cout << endl;

	s.Append(" world");
	cout << s << endl;

	s += s1;
	cout << s << endl;

	s.Insert(13, "my name is qujiale, ");
	cout << s << endl;

	cout << s.Size() << endl;
}

int main()
{
	test();
	return 0;	
}

运行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值