(十四)String类底层代码剖析

#define _CRT_SECURE_NO_WARNINGS

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


namespace weige {

	class String
	{
	public:
		typedef char* iterator;
		String(const char* str = "")
		{
			if (nullptr == str)
			{
				str = "";
			}
			_str = new char[strlen(str) + 1];
			strcpy(_str, str);
			_size = strlen(str);
			_capacity = _size;
		}
		String(int n, char ch)
		{
			_str = new char[n + 1];
			memset(_str, ch, n);
			_size = n;
			_capacity = n;
			_str[_size] = '\0';
		}
		String(const String& s)
			: _str(nullptr)
		{
			String temp(s._str);
			this->swap(temp);
		}
		String& operator=(String s)
		{
			this->swap(s);
			return *this;
		}
		void swap(String& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		~String()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
				_size = 0;
				_capacity = 0;
			}
		}
		size_t size() const
		{
			return _size;
		}
		size_t length()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}
		char& operator[] (size_t pos)
		{
			if (pos >= _size)
				assert(0);
			return _str[pos];
		}
		const char& operator[] (size_t pos) const
		{
			if (pos >= _size)
				assert(0);
			return _str[pos];
		}
		char& at(size_t pos)
		{
			return _str[pos];
		}
		const char& at(size_t pos)const
		{
			return _str[pos];
		}
		void clear()
		{
			_size = 0;
		}
		bool empty()const
		{
			return 0 == _size;
		}
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		void resize(size_t n)
		{
			resize(n, '\0');
		}
		void resize(size_t newsize, char val)
		{
			size_t oldsize = _size;
			if (newsize > capacity())
				reserve(newsize);
			memset(_str + _size, val, newsize - oldsize);

			_size = newsize;
			_str[_size] = '\0';
		}
		void reserve(size_t newcapacity = 0)
		{
			size_t oldcapacity = capacity();
			if (newcapacity > oldcapacity)
			{
				char* temp = new char[newcapacity + 1];
				strncpy(temp, _str, _size);
				delete[] _str;
				_str = temp;
				_capacity = newcapacity;
				_str[_size] = '\0';
			}
		}
		void push_back(char c)
		{
			*this += c;
		}
		void pop_back()
		{
			_size -= 1;
		}
		String& operator+=(const String& s)
		{
			*this += s.c_str();
			return *this;
		}
		const char* c_str()const
		{
			return _str;
		}
		String& operator+=(const char* str)
		{
			size_t newsize = _size + strlen(str);
			size_t leavesize = _capacity - _size;
			if (leavesize < newsize)
				reserve(newsize + 1);
			strcat(_str, str);
			_str[newsize] = '\0';
			_size = newsize;
			_capacity = newsize + 1;
			return *this;
		}
		String& operator+=(char ch)
		{
			if (_size == _capacity)
				reserve((size_t)_capacity * 1.5 + 3);
			_str[_size] = ch;
			_str[_size + 1] = '\0';
			_size = _size + 1;
			return *this;
		}
		String& append(const String& str)
		{
			*this += str.c_str();
			return *this;
		}
		String& append(const char* str)
		{
			*this += str;
			return *this;
		}
		String& append(size_t n, char ch)
		{
			for (size_t i = 0; i < n; i++)
				*this += ch;
			return *this;
		}
		String& erase(size_t pos = 0, size_t len = npos)
		{
			if (pos + len >= _size)
			{
				_size = pos;
				_str[_size] = '\0';
			}
			else
			{
				size_t start = pos+len;
				strcpy(_str + pos, _str + start);
				_size -= len;
			}
			return *this;
		}
		size_t find(const string& str, size_t pos = 0) const
		{
			return find(str.c_str());
		}
		size_t find(const char* s, size_t pos = 0) const
		{
			if (pos >= _size)
			{
				return npos;
			}
			char* res;
			res = strstr(_str, s);
			if (res == nullptr)
				return npos;
			else
				return res - _str;	// 相对于首部的偏移量
		}
		//通用Insert接口
		void Insert(size_t pos, char ch) {
			assert(pos <= _size);

			if (_size == _capacity) {
				reserve(_capacity * 2);
			}

			for (size_t i = _size; i >= pos; --i) {		//从'\0'开始挪动数据
				_str[i + 1] = _str[i];
			}
			_str[pos] = ch;
			_size++;
		}

		void Insert(size_t pos, const char* str) {
			assert(pos <= _size);

			size_t len = strlen(str);
			if (_size + len > _capacity) {
				reserve(_size + len);
			}
			for (size_t i = _size; i >= pos; --i) {
				_str[i + len] = _str[i];
			}
			strncpy(_str + pos, str, len);
			_size += len;
		}
		size_t find(char c, size_t pos = 0) const
		{
			if (pos >= _size)
			{
				return npos;
			}
			else
			{
				for (size_t i = pos; i < _size; ++i)
				{
					if (c == _str[i])
						return i;
				}
				return npos;
			}

		}
		String substr(size_t pos = 0, size_t len = npos) const
		{
			if (pos >= _size)
				return String();
			len = min(len, _size - pos);
			String temp(len, '\0');
			size_t index = 0;
			for (size_t i = pos; i < pos + len; i++)
				temp[index++] = _str[i];
			return temp;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		const static size_t npos = -1;
		friend ostream& operator<<(ostream& out, const String& s);
	};
	ostream& operator<<(ostream& out, const String& s)
	{
		for (size_t i = 0; i < s.size(); i++)
		{
			cout << s[i];
		}
		cout << endl;
		return out;
	}
}

void Test01()
{
	weige::String s1("hello");
	weige::String s2(s1);
}

void Test02()
{
	weige::String s1("hello world");
	weige::String s2;
	s2 = s1;
	cout << s1 << endl;
}

void Test03()
{
	weige::String s1("hello world");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('a');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('b');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('c');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('d');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('e');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('f');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('g');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('h');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
}

void Test04()
{
	weige::String s1("hello world");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.push_back('a');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('b');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('c');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('d');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('e');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('f');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('g');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += ('h');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
}

void Test05()
{
	weige::String s1("hello world");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1 += "abc";
	cout << s1 << endl;
	const char* temp = "aaaaa";
	s1 += temp;
	cout << s1 << endl;
}

void Test06()
{
	weige::String s1("hello world");
	weige::String s2("hello");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.append(10, ' ');
	cout << s1 << endl;
	s1.append("abcdef");
	cout << s1 << endl;
	s1.append(s2);
	cout << s1 << endl;
}

void Test07()
{
	weige::String s1("hello world");
	weige::String s2;
	size_t pos = s1.find(' ');
	s2 = s1.substr(pos + 1);
	cout << s1 << endl << s2 << endl;
}

void Test08()
{
	weige::String s1("hello world");
	weige::String s2(s1);
	s1.erase(0);
	s2.erase(5, 5);
	cout << s1 << endl << s2 << endl;
}

int main()
{
	// Test01();
	// Test02();
	// Test03();
	// Test04();
	// Test05();
	// Test06();
	// Test07();
	Test08();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值