string类的实现

string.h

cpp 复制代码
#pragma once
#include<iostream>
#include<cstring>
#include<cassert>
#include<algorithm>
using namespace std;
namespace my_string {
	class string {
		friend ostream& operator<<(ostream& _cout, const my_string::string& s);
		friend istream& operator>>(istream& _cin, my_string::string& s);
	public:
		static const size_t npos;
		typedef char* iterator;
		//string();
		string(const char* str="");
		const char* c_str() const;
		string(const string& s);
		~string();
		// iterator
		iterator begin() {
			return _str;
		}
		iterator end() {
			return _str + _size;
		}
		// modify
		void push_back(char c);
		string& operator+=(char c);
		void append(const char* str);
		string& operator+=(const char* str);
		void clear();
		void swap(string& s);
		// capacity
		size_t size()const;
		size_t capacity()const;
		bool empty()const;
		void resize(size_t n, char c = '\0');
		void reserve(size_t n);
		// access
		char& operator[](size_t index);
		const char& operator[](size_t index)const;
		//relational operators
		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);
		// 返回c在string中第一次出现的位置
		size_t find(char c, size_t pos = 0) const;
		// 返回子串s在string中第一次出现的位置
		size_t find(const char* s, size_t pos = 0) const;
		// 在pos位置上插入字符c/字符串str,并返回该字符的位置
		string& insert(size_t pos, char c);
		string& insert(size_t pos, const char* str);
		// 删除pos位置上的元素,并返回该元素的下一个位置
		string& erase(size_t pos, size_t len);
	private:
		
		size_t _size;
		size_t _capacity;
		char* _str;
	};
}

string.cpp

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "String.h"
namespace my_string
{
	/*string::string()
		:_str(new char[1] {'\0'})
		, _size(0)
		, _capacity(0)
	{}*/
	string::string(const char* str)
		:_size(strlen(str))
		, _capacity(_size)
		, _str(new char[_size + 1])
	{
		strcpy(_str, str);
	}
	const char* string::c_str() const {
		return _str;
	}
	string::string(const string& s) {
		_size = s._size;
		_capacity = s._capacity;
		_str = new char[_capacity + 1];
		strcpy(_str, s.c_str());
	}

	string::~string() {
		delete[] _str;
		_str = nullptr;
		_size = _capacity = 0;
	}
	void string::push_back(char c)
	{
		if(_size >=_capacity) {
			size_t new_capacity = (_capacity == 0) ? 4 : 2 * _capacity;
			reserve(new_capacity);
		}
		_str[_size] = c;
		_size++;
		_str[_size] = '\0';
	}
	string& string::operator+=(char c)
	{
		push_back(c);
		return *this;
	}

	void string::append(const char* str)
	{
		if (str == nullptr) {
			return;
		}
		size_t len = strlen(str);
		size_t new_size = _size + len;
		if (new_size > _capacity) {
			// 扩容到刚好容纳新内容(或翻倍,取较大者)
			size_t new_capacity = max(_capacity * 2, new_size);
			reserve(new_capacity);
		}
		for (size_t i = 0; i < len; ++i) {
			_str[_size + i] = str[i];
		}
		_size += len;
		_str[_size] = '\0';
	}

	string& string::operator+=(const char* str)
	{
		append(str);
		return *this;
	}
	void string::clear() {
		if (_size > 0) {
			_str[0] = '\0';
			_size = 0;
		}
	}
	void string::swap(string& s) {
		std::swap(_str, s._str);
		std::swap(_size, s._size);
		std::swap(_capacity, s._capacity);
	}
	size_t string::size() const {
		return _size;
	}
	size_t string::capacity()const {
		return _capacity;
	}
	bool string::empty()const {
		return _size == 0;
	}
	void string::resize(size_t n, char c)
	{
		if (n > capacity()) {
			char* new_str = new char[n + 1];
			strcpy(new_str, _str);
			delete[] _str;
			_str = new_str;
			_capacity = n;
		}
		if (n > _size) {
			for (size_t i = _size; i < n; i++) {
				_str[i] = c;
			}
		}
		_size = n;
		_str[_size] = '\0';
	}
	void string::reserve(size_t n) {
		if (n > capacity()) {
			char* new_str = new char[n + 1];
			for (size_t i = 0; i < _size; ++i) { 
				new_str[i] = _str[i];
			}
			new_str[_size] = '\0'; 
			delete[] _str;
			_str = new_str;
			_capacity = n;
		}
	}
	char& string::operator[](size_t index) {
		assert(index < _size);
		return _str[index];
	}
	const char& string::operator[](size_t index)const {
		assert(index < _size);
		return _str[index];
	}
	bool string::operator<(const string& s)
	{
		for(size_t i = 0; i < _size && i < s._size; ++i) {
			if (_str[i] < s._str[i]) {
				return true;
			}
			else if (_str[i] > s._str[i]) {
				return false;
			}
		}
		// 前面字符相等时,短字符串更小
		return _size < s._size;
	}

	bool string::operator==(const string& s)
	{
		if(_size != s._size) {
			return false;
		}
		for(size_t i = 0; i < _size; ++i) {
			if(_str[i] != s._str[i]) {
				return false;
			}
		}
		return true;
	}

	bool string::operator!=(const string& s)
	{
		return !((*this) == s);
	}

	bool string::operator<=(const string& s)
	{
		return ((*this) < s || (*this) == s );
	}

	bool string::operator>(const string& s)
	{
		return !((*this) <= s);
	}
	bool string::operator>=(const string& s) {
		return !((*this) < s);
	}
	size_t string::find(char c, size_t pos) const
	{
		for(size_t i = pos; i < _size; ++i) {
			if(_str[i] == c) {
				return i;
			}
		}
		return string::npos;
	}
	size_t string::find(const char* s, size_t pos) const
	{
		if(s == nullptr) {
			return string::npos;
		}
		size_t len = strlen(s);
		if(len + pos > _size) {
			return string::npos;
		}
		for (size_t i = pos; i < _size - len; i++) {
			size_t j = 0;
			while(j<len&&_str[i + j] == s[j]) {
				j++;
			}
			if(j == len) {
				return i;
			}
		}
		return string::npos;
	}
	string& string::insert(size_t pos, char c)
	{
		if(pos > _size) {
			return *this;
		}
		if(_size >= _capacity) {
			_capacity = 2 * _size;
			char* new_str = new char[_capacity + 1];
			strcpy(new_str, _str);
			delete[] _str;
			_str = new_str;
		}
		for (size_t i = _size; i > pos; i--) {
			_str[i] = _str[i - 1];
		}
		_str[pos] = c;
		_size++;
		_str[_size] = '\0';
		return *this;
	}
	string& string::insert(size_t pos, const char* str)
	{
		if (str == nullptr||pos>_size) {
			return *this;
		}
		size_t len = strlen(str);
		if (_size + len > _capacity) {
			do {
				_capacity = 2 * _capacity;
			} while (_size + len > _capacity);
			reserve(_capacity);
		}
		for (size_t i = _size; i > pos; --i) {
			_str[i + len - 1] = _str[i - 1];
		}
		for(size_t i = 0; i < len; ++i) {
			_str[pos + i] = str[i];
		}
		_size += len;
		_str[_size] = '\0';
		return *this;
	}
	string& string::erase(size_t pos, size_t len)
	{
		if(pos >= _size) {
			return *this;
		}
		if(len == npos || pos + len >= _size) {
			_str[pos] = '\0';
			_size = pos;
			return *this;
		}
		for(size_t i = pos + len; i < _size; ++i) {
			_str[i - len] = _str[i];
		}
		_size -= len;
		_str[_size] = '\0';
		return *this;
	}
	const size_t string::npos = -1;
	ostream& operator<<(ostream& _cout, const my_string::string& s)
	{
		_cout << s.c_str();
		return _cout;
	}
	istream& operator>>(istream& _cin, my_string::string& s)
	{
		s.clear();
		_cin >> s._str;
		s += s._str;
		return _cin;
	}
}
相关推荐
励志五个月成为嵌入式糕手4 小时前
0904 类的继承
开发语言·c++
励志不掉头发的内向程序员4 小时前
从零开始的python学习——列表
开发语言·python·学习
CHANG_THE_WORLD4 小时前
线程特定存储
算法·线程
ai产品老杨4 小时前
打破技术壁垒,推动餐饮食安标准化进程的明厨亮灶开源了
前端·javascript·算法·开源·音视频
睡不醒的kun4 小时前
leetcode算法刷题的第二十六天
数据结构·c++·算法·leetcode·职场和发展·贪心算法
一匹电信狗4 小时前
【Linux我做主】细说进程等待
linux·运维·服务器·c++·ubuntu·小程序·开源
玖釉-5 小时前
OpenGL视图变换矩阵详解:从理论推导到实战应用
c++·图形渲染
fangzelin55 小时前
基础排序--冒泡--选择--插入
数据结构·c++·算法
THMAIL5 小时前
机器学习从入门到精通 - 卷积神经网络(CNN)实战:图像识别模型搭建指南
linux·人工智能·python·算法·机器学习·cnn·逻辑回归