【C++】模拟实现STL string类

前面博客 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值