当前位置 博文首页 > chenxiyuehh的博客:【C++】模拟实现STL string类

    chenxiyuehh的博客:【C++】模拟实现STL string类

    作者:[db:作者] 时间:2021-08-19 15:44

    前面博客 STLstring类相关接口介绍 中对string的接口进行了详细的介绍和测试,下面我们将对这些接口进行模拟实现,若有疑问可参考前面的博客。

    STL string模拟实现源码

    头文件String.h

    #pragma once
    #include <iostream>
    #include <string.h>
    #include <string>
    #include <assert.h>
    using namespace std;
    
    namespace CXY
    {
    	class String
    	{
    	public:
    		typedef char* Iterator;//迭代器
    		Iterator begin()
    		{
    			return _str;//返回字符串开头位置
    		}
    		Iterator end()
    		{
    			return _str + _size;//返回字符串结束的位置
    		}
    
    	public:
    		//String();//无参构造函数
    		//String(const char* str);//带参构造函数
    		String(const char* str = "");//带缺省参数的构造函数
    		String(const String& str);//拷贝构造函数
    		String& operator=(const String& str);//重载赋值运算符
    		~String();//析构函数
    		bool operator<(const String& s);
    		bool operator>(const String& s);
    		bool operator<=(const String& s);
    		bool operator>=(const String& s);
    		bool operator==(const String& s);
    		bool operator!=(const String& s);
    
    		void Swap(String& str);
    		const char* C_str() const;
    		char& operator[](size_t pos);
    		size_t Size();
    		size_t Capacity();
    		
    		void Reserve(size_t n);
    		void PushBack(char ch);
    		void Append(const char* str);
    		
    
    		String& operator+=(char ch);
    		String& operator+=(const char* str);
    		void Insert(size_t pos, char ch);
    		void Insert(size_t pos, const char* str);
    
    		void Erase(size_t pos, size_t len);
    		size_t Find(char ch, size_t pos = 0);
    		size_t Find(const char* str, size_t pos = 0);
    
    
    	private:
    		char* _str;
    		size_t _size;
    		size_t _capacity;
    
    		static size_t npos;
    	};
    	size_t String::npos = -1;
    	void TestString()
    	{
    		String s1("hello world");
    		cout << s1.C_str() << endl;
    		String s2(s1);
    		cout << s2.C_str() << endl;
    		String s3("world");
    		cout << (s1 < s3) << endl;
    		cout << (s1 == s2) << endl;
    		cout << (s1 > s3) << endl;
    
    		//s1.PushBack('w');
    		//cout << s1.C_str() << endl;
    		//s2.Append(" world");
    		//cout << s2.C_str() << endl;
    
    		//s3 += 'w';
    		//cout << s3.C_str() << endl;
    
    		//s3 += " hello";
    		//cout << s3.C_str() << endl;
    
    		//s1.Insert(3, 'a');
    		//cout << s1.C_str() << endl;
    
    		//s1.Insert(3, "whkk");
    		//cout << s1.C_str() << endl;
    
    
    		//s1.Erase(2, 2);
    		//cout << s1.C_str() << endl;
    
    		//cout << s1.Find('e') << endl;
    
    		cout << s1.Find("world") << endl;
    	}
    }
    

    成员函数实现文件 String.cpp

    #define _CRT_SECURE_NO_WARNINGS
    #include "String.h"
    
    using namespace std;
    using namespace CXY;
    
    //String::String()
    //:_str(new char[1])
    //{
    //	_str[0] = '\0';
    //}
    
    //带参构造函数
    //String::String(const char* str)
    //:_str(new char[strlen(str)+1])
    //{
    //	strcpy(_str, str);
    //}
    
    //带缺省参数的构造函数
    String::String(const char* str)
    {
    	assert(str);
    
    	_size = strlen(str);
    	_capacity = _size;
    	_str = new char[_capacity + 1];
    	strcpy(_str, str);
    }
    
    String::~String()//析构函数
    {
    	if (_str)
    	{
    		delete[] _str;
    		_size = 0;
    		_capacity = 0;
    	}
    }
    
    
    void String::Swap(String& str)
    {
    	swap(_str, str._str);
    	swap(_size, str._size);
    	swap(_capacity, str._capacity);
    }
    //拷贝构造函数传统写法
    //String::String(const String& str)
    //:_str(new char[str._capacity+1])
    //, _size(str._size)
    //, _capacity(str._capacity)
    //{
    //	strcpy(_str, str._str);
    //}
    //拷贝构造函数现代写法
    // copy(s1)
    
    String::String(const String& str)
    :_str(nullptr)
    , _size(0)
    , _capacity(0)
    {
    	String tmp(str._str);
    	this->Swap(tmp);
    }
    
    bool String::operator<(const String& s)
    {
    	if (strcmp(_str, s._str) < 0)
    		return true;
    	else
    		return false;
    	      
    }
    
    bool String::operator==(const String& s)
    {
    	if (strcmp(_str, s._str) == 0)
    		return true;
    	else
    		return false;
    }
    
    bool String::operator>(const String& s)
    {
    	return !((_str < s._str) || (_str == s._str));
    }
    
    bool String::operator<=(const String& s)
    {
    	return !(_str > s._str);
    }
    
    bool String::operator>=(const String& s)
    {
    	return !(_str < s._str);
    }
    
    //重载访问运算符[]
    char& String::operator[](size_t pos)
    {
    	assert(pos < _size);
    	return _str[pos];
    }
    
    //求字符串长度
    size_t String::Size()
    {
    	return _size;
    }
    
    //求字符串空间大小
    size_t String::Capacity()
    {
    	return _capacity;
    }
    
    //为字符串预留空间
    void String::Reserve(size_t newcapacity)
    {
    	//如果旧容量小于新容量,开辟新空间
    	if (newcapacity > _capacity)
    	{
    		//开辟新空间,将原空间的字符串拷贝到新空间
    		char* tmp = new char[newcapacity+1];
    		assert(tmp);
    		strcpy(tmp, _str);
    
    		//释放旧空间,使用新空间
    		delete[] _str;
    		_str = tmp;
    		_capacity = newcapacity;
    	}
    	
    }
    
    //在字符串后追加一个字符
    void String::PushBack(char ch)
    {
    	//if (_size == _capacity)
    	Reserve(_capacity * 2);
    	_str[_size] = ch;
    	++_size;
    	_str[_size] = '\0';
    }
    
    //在字符串后追加一个字符串
    // "hello"  "xxxxxxxxxxxxxxxxxxxxxxxxxx"
    void String::Append(const char* str)
    {
    	// 判断追加字符串是否到达了最大容量,是就增容
    	//if (_size == _capacity)
    	Reserve(_size + strlen(str) + 1);
    
    	strcpy(_str + _size, str);
    	_size += strlen(str);
    }
    const char* String::C_str() const
    {
    	return _str;
    }
    
    //重载运算符+=
    String& String::operator+=(char ch)
    {
    	PushBack(ch);
    	return *this;
    }
    
    String& String::operator+=(const char* str)
    {
    	Append(str);
    	return *this;
    }
    
    //在指定位置pos处插入字符ch
    void String::Insert(size_t pos, char ch)
    {
    	Reserve(_capacity * 2);
    
    	for (size_t i = _size; i >= pos; --i)
    	{
    		_str[i + 1] = _str[i];
    	}
    
    	_str[pos] = ch;
    	++_size;
    }
    
    //在指定位置pos处插入字符串str
    void String::Insert(size_t pos, const char* str)
    {
    	Reserve(_size + strlen(str) + 1);
    
    	size_t gap = strlen(str);
    	for (size_t i = _size; i >= pos; --i)
    	{
    		_str[i + gap] = _str[i];
    	}
    
    	for (size_t i = 0; i < gap; ++i)
    	{
    		Insert(pos, str[i]);
    		++pos;
    	}
    	_size += gap;
    }
    
    //在指定位置pos处删除长度为len的字符串
    void String::Erase(size_t pos, size_t len)
    {
    	for (size_t i = pos + len; i <= _size; ++i)
    	{
    		_str[pos] = _str[i];
    		++pos;
    	}
    	_size -= len;
    }
    
    //在字符串中寻找一个字符ch,返回该字符的下标
    size_t String::Find(char ch, size_t pos)
    {
    	for (size_t i = pos; i < _size; ++i)
    	{
    		if (_str[i] == ch)
    			return i;
    	}
    	return npos;
    }
    
    size_t String::Find(const char* str, size_t pos)
    {
    	size_t begin = Find(str[0]);
    	size_t index = begin;
    	int len = strlen(str);
    	while (begin < _size)
    	{
    		int i = 0;
    		char* arr = _str + begin;
    		while (i < len)
    		{
    			if (arr[i] == str[i])
    				++i;
    			else
    				break;
    		}
    		if (i == len)
    			return index;
    	}
    	return npos;
    }
    
    
    int main()
    {
    	CXY::TestString();
    	return 0;
    }
    
    cs