当前位置: 首页> 科技> 能源 > C++ string类的模拟实现

C++ string类的模拟实现

时间:2025/7/11 19:57:09来源:https://blog.csdn.net/Alenenen/article/details/141099095 浏览次数:0次

这篇文章,主要就是展示模拟实现C++标准库中的string类的代码,下面就是具体的代码,同时也上传了具体的文件。

string.h(头文件)

// string.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
using namespace std;
#include <assert.h>namespace Alen
{class string{// 类里面定义的成员函数默认是内敛函数,内敛不会放在符号表所以不会链接错误public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}// 深拷贝问题// 写法一:老写法/*string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}*/void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}// 方法二:string(const string& s){string tmp(s._str);swap(tmp);}//string& operator=(const string& s)//{//	if (this != &s)//	{//		/*delete[] _str;//		_str = new char[s._capacity + 1];//		strcpy(_str, s._str);//		_size = s._size;//		_capacity = s._capacity;*///		//string tmp(s._str);//		string tmp(s);//		swap(tmp);//		//	}//	return *this;//}string& operator=(string tmp){swap(tmp);return *this;}~string()	{if (_str){delete[] _str;		// delete中对nullptr特别处理了,也可以不需要手动判断_str = nullptr;_size = _capacity = 0;}}const char* c_str() const	{return _str;}void reserve(size_t newCapacity);void clear();void push_back(char c);string& operator+=(char c);void append(const char* s);string& operator+=(const char* s);void insert(size_t pos, char ch);void insert(size_t pos, const char* s);void erase(size_t pos, size_t len = npos);size_t find(char c, size_t pos = 0);size_t find(const char* s, size_t pos = 0);string substr(size_t pos = 0, size_t len = npos);private:char* _str = nullptr;size_t _capacity;size_t _size;static const size_t npos;};bool operator<(const string& s1, const string& s2);bool operator<=(const string& s1, const string& s2);bool operator>(const string& s1, const string& s2);bool operator>=(const string& s1, const string& s2);bool operator==(const string& s1, const string& s2);bool operator!=(const string& s1, const string& s2);// 加不加const取决于读还是写ostream& operator<<(ostream& out, const string& s);istream& operator>>(istream& in, string& s);istream& getline(istream& in, string& s, char delim = '\n');
}

string.cpp

// string.cpp
#include "string.h"
namespace Alen
{const size_t string::npos = -1;void string::reserve(size_t newCapacity){if (newCapacity > _capacity){char* tmp = new char[newCapacity + 1];	// 多一个空间存'\0'strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = newCapacity;}}void string::clear(){_str[0] = '\0';_size = 0;}void string::push_back(char c){if (_size == _capacity)reserve(_capacity == 0 ? 4 : _capacity * 2);		// 进行2倍扩容_str[_size++] = c;_str[_size] = '\0';		// !!!}string& string::operator+=(char c){push_back(c);return *this;}void string::append(const char* s){size_t len = strlen(s);if (_size + len > _capacity){reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);}strcpy(_str + _size, s);_size += len;}string& string::operator+=(const char* s){append(s);return *this;}void string::insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity)reserve(_capacity == 0 ? 4 : _capacity * 2);// 挪动数据// end 是int类型,pos是size_t类型,比较会将end隐式类型转换成size_t// 当end为-1的(即pos为0)时候,就成为了size_t的最大值//int end = _size;//while (end >= pos)		//{//	_str[end + 1] = _str[end];//	--end;//}//_str[pos] = ch;//++_size;size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;}void string::insert(size_t pos, const char* s){assert(pos <= _size);size_t len = strlen(s);if (_size + len > _capacity)reserve(_size + len > 2 * _capacity ? _size + len : 2 * _capacity);// 挪动数据size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];}for (size_t i = 0; i < len; i++){_str[pos + i] = s[i];}}void string::erase(size_t pos, size_t len){assert(pos < _size);if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{for (size_t i = pos + len; i <= _size; i++){_str[i - len] = _str[i];}_size -= len;}}size_t string::find(char c, size_t pos){for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}return npos;}// 可以使用KMP、BM算法size_t string::find(const char* s, size_t pos){assert(pos < _size);const char* ptr = strstr(_str + pos, s);if (ptr == nullptr){return npos;}else{return ptr - _str;}}string string::substr(size_t pos, size_t len){assert(pos < _size);if (len > _size - pos){len = _size - pos;}string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}bool operator<(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str()) < 0;}bool operator<=(const string& s1, const string& s2){return s1 < s2 || s1 == s2;}bool operator>(const string& s1, const string& s2){return !(s1 <= s2);}bool operator>=(const string& s1, const string& s2){return !(s1 < s2);}bool operator==(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str()) == 0;}bool operator!=(const string& s1, const string& s2){return !(s1 == s2);}ostream& operator<<(ostream& out, const string& s){for (auto ch : s){out << ch;}return out;}void IN(istream& in ,string& s, char option = '\n'){char ch;const int N = 256;char buff[N];	// 利用缓存区的思路,来减少string的扩容操作,增加效率int i = 0;ch = in.get();	// = C语言的getc一个字符一个字符读while (option == ' ' ? ch != ' ' && ch != '\n' : ch != option){buff[i++] = ch;if (i == N - 1){buff[i] = '\0';s += buff;i = 0;}//s += ch;ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}}istream& operator>>(istream& in, string& s){s.clear();/*char ch;//in >> ch;		// 将 ' ' 与 '\n'作为分隔符,直接忽视不会读取 //while (ch != ' ' && ch != '\n')//{//	s += ch;//	in >> ch;//}const int N = 256;char buff[N];	// 利用缓存区的思路,来减少string的扩容操作,增加效率int i = 0;ch = in.get();	// = C语言的getc一个字符一个字符读while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == N - 1){buff[i] = '\0';s += buff;i = 0;}//s += ch;ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}*/IN(in, s, ' ');return in;}istream& getline(istream& in, string& s, char delim){s.clear();IN(in, s, delim);return in;}}

Test.cpp(测试文件 / 主函数)

// Test.cpp
#include "string.h"namespace Alen
{void teststring1(){string s("hello world");s += 's';s += "abc";for (auto& ch : s){ch += 1;}cout << s.c_str() << endl;}void teststring2(){string s("hello world");s.erase(6, 3);cout << s.c_str() << endl;}void teststring3(){string s("test.cpp.zip");size_t pos1 = s.find('.');size_t pos2 = s.find("cpp");string suffix1 = s.substr(pos1);string suffix2 = s.substr(pos2);cout << suffix1.c_str() << endl;cout << suffix2.c_str() << endl;}void teststring4(){string s1("hello world");string s2("hello world");cout << (s1 < s2) << endl;cout << (s1 == s2) << endl;cout << ("hello world" < s2) << endl;cout << (s1 == "hello world") << endl;	// 将 "hello world"隐式类型转换成string临时对象cout << ("hello world" == "hello world") << endl;	// 两个指针的比较(运算符重载必须有一个对应的对象识别)}void teststring5(){string s("hello world");string s1 = s;getline(cin, s);getline(cin, s, '*');cout << s << endl;}}int main()
{//Alen::teststring5();return 0;
}
关键字:C++ string类的模拟实现

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: