栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

<string类模拟实现>——《C++初阶》

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

<string类模拟实现>——《C++初阶》

为实现祖国统一而奋斗!为实现社会主义现代化而奋斗!为实现中华民族复兴而奋斗!
                                                                     ——By  一名社会主义建设积极分子 

目录

一、实现概括:

1.先实现一个简单的string,只考虑资源管理深浅拷贝问题(暂不考虑增删查改)

      对于浅拷贝的两个问题:

2. string完善的增、删、查、改、使用的string 

完整源码及注释:

后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!                                     ——By 作者:新晓·故知 


一、实现概括:

模拟实现string类,最主要是实现string类的构造、拷贝构造、赋值运算符重载以及析构函数。根据string的底层原理,实现模拟string使其与库里的string(即std::string)具有相似的功能。由于库里的string类的功能较多,这里只模拟实现了较为常用的功能,

例如:iterator(模拟的string迭代器)、push_back、insert、reserve、resize、find、erase、c_str、ostream重载、istream重载、赋值运算符重载、[ ]重载、append以及比较运算符的重载等,甚至深拷贝构造函数的现代写法(资本写法)、赋值运算符重载的现代写法(资本写法)等。std::string中的功能较多,学习使用可登录cplusplus官网,参见string文档。

1.先实现一个简单的string,只考虑资源管理深浅拷贝问题(暂不考虑增删查改)

(1)string.h

(2)test.cpp:

 

深拷贝:

深拷贝:使得值相同,空间大小相同,但空间地址不同

 

对于浅拷贝的两个问题:

1.多次析构同一空间:引用计数,即最后一个拷贝构造的对象是否资源

2.一个对象修改会影响其他对象:做深拷贝,写时拷贝

2. string完善的增、删、查、改、使用的string 

 string.h:

 test.cpp:

完整源码及注释:

(1)string.h:

#pragma once
#define _CRT_SECURE_NO_WARNINGS

#include
#include
#include
using namespace std;
//模拟实现string

//1.先实现一个简单的string,只考虑资源管理深浅拷贝问题
//自定义命名空间,防止与库中的冲突
//namespace my
//{
//	//先实现一个简单的string,只考虑资源管理深浅拷贝问题
//	//暂不考虑增删查改
//	class string
//	{
//	public:
//		//构造函数
//		string(const char* str)
//			:_str(new char[strlen(str) + 1])  
//		{
//			//不能直接 _str=str; 因为会权限放大
//			strcpy(_str, str);  //也拷贝了
//		}
//		//深拷贝函数 s2(s1)
//		string(const string& s)
//			:_str(new char[strlen(s._str) + 1])
//		{
//			strcpy(_str, s._str);
//		}
//		~string()
//		{
//			if (_str)
//			{
//				delete[] _str;
//			}
//		}
//		//s1=s3  ——>s1.operator=(&s1,s3)
//		//赋值重载函数
//		string& operator = (const string& s)
//		{
//			if (this != &s)  //解决s1=s1,自己释放自己的空间
//			{
//				//先删除,再开辟赋值
//				//如果new开辟失败,那s1作为原始数据被删除
//				
//				//先保存,再开辟赋值
//				char* tmp = new char[strlen(s._str) + 1];
//				strcpy(tmp, s._str);
//				delete[] _str;
//				_str = tmp;
//			}
//		    return *this;
//		}
//		//c_str是string中的一个函数,具体详见string文档
//		//获取等效的字符串
//		const char* c_str() const
//		{
//			return _str;
//		}
//		//重载[]
//		char& operator[](size_t pos)
//		{
//			assert(pos < strlen(_str));
//			return _str[pos];
//		}
//		//计算字符串大小
//		size_t size()
//		{
//			return strlen(_str);
//		}
//          
//	private:
//		char* _str;
//
//	};
//}

//
2.string完善的增删查改和使用的string
//namespace my
//{
//	class string
//	{
//	public:
//		构造函数
//		//string(const char* str)
//		//	:_size(strlen(str))
//		//	,_capacity(_size)
//		//{
//		//	//要注意初始化顺序,取决于类的声明顺序
//		//	_str = new char[_capacity + 1];
//		//	//不能直接 _str=str; 因为会权限放大
//		//	strcpy(_str, str);  //也拷贝了
//		//}
//		默认构造函数(无参使用的)
//		//string()
//		//	:_size(0)
//		//	,_capacity(0)
//		//{
//		//	_str = new char[1];  //将_str初始化为空字符串,string库就是这种做法
//		//	_str[0] = '0';
//		//}
//		
//		//默认构造函数(全缺省版)
//		string(const char* str="") // ""、""均可以,''是字符
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			//要注意初始化顺序,取决于类的声明顺序
//			_str = new char[_capacity + 1];
//			//不能直接 _str=str; 因为会权限放大
//			strcpy(_str, str);  //也拷贝了
//		}
//		深拷贝函数版本1 s2(s1)
//		//string(const string& s)
//		//	:_str(new char[strlen(s._str) + 1])
//		//{
//		//	strcpy(_str, s._str);
//		//}
//	    //深拷贝函数版本2 s2(s1)
//		string(const string& s)
//			:_size(strlen(s._str))
//			,_capacity(_size)
//		{
//			_str=new char[_capacity + 1];
//			strcpy(_str, s._str);
//		}
//		
//		//析构函数
//		~string()
//		{
//			if (_str)
//			{
//				delete[] _str;
//			}
//		}
//		//s1=s3  ——>s1.operator=(&s1,s3)
//		//赋值重载函数
//		string& operator = (const string& s)
//		{
//			if (this != &s)  //解决s1=s1,自己释放自己的空间
//			{
//				//先保存,再开辟赋值
//				char* tmp = new char[s._capacity + 1];
//				strcpy(tmp, s._str);
//				delete[] _str;
//				_str = tmp;
//				_size = s._size;
//				_capacity = s._capacity;
//			}
//			return *this;
//		}
//		//c_str是string中的一个函数,具体详见string文档
//		//获取等效的字符串
//		const char* c_str() const
//		{
//			return _str;
//		}
//		//重载[]
//		char& operator[](size_t pos)
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//		//重载[] const 提供两个版本的重载[] ,普通对象和const对象都可以调用
//		const char& operator[](size_t pos) const
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//		//计算字符串大小
//		//size_t size(const string* this)
//		size_t size() const
//		{
//			return _size;
//		}
//
//		size_t capacity() const
//		{
//			return _capacity;
//		}
//		尾插数据
//		//void push_back(char ch)
//		//{
//		//	if (_size == _capacity) //其实为_capacity开辟的多一个为存储的空间,但那个不参与比较
//		//	{
//		//		char* tmp = new char[_capacity * 2 + 1];
//		//		strcpy(tmp, _str);
//		//		delete[] _str;
//		//		_str = tmp;
//		//		_capacity *= 2;
//		//	}
//		//	_str[_size] = ch;
//		//	++_size;
//		//	_str[_size] = '';
//		//}
//		
//		//尾插也可以使用+=(附用push_back)
//		string& operator+=(char ch) 
//		{
//			push_back(ch);
//			return *this;
//		}
//		//预留扩容
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//				_capacity = n;
//			}
//		}
//		//尾插数据——附用reserve
//		void push_back(char ch)
//		{
//			//if (_size == _capacity) //其实为_capacity开辟的多一个为存储的空间,但那个不参与比较
//			//{
//			//	//reserve( _capacity * 2);若_capacity为0,则出现bug
//			//	reserve(_capacity==0 ? 4 : _capacity * 2);
//			//}
//			//_str[_size] = ch;
//			//++_size;
//			//_str[_size] = '';
//			
//			//附用insert
//			insert(_size, ch);
//		}
//		//追加到字符
//		void append(const char*str)
//		{
//			
//			//附用insert
//			insert(_size, str);
//		}
//		//尾插也可以使用+=(附用append)
//		string& operator+=(const char* str) 
//		{
//			append(str);
//			return *this;
//		}
//		//扩空间+初始化
//		//删除部分数据,保留前n个
//		void resize(size_t n, char ch = '')
//		{
//			//考虑到内存对齐,可能开辟的空间与n有些许微小出入
//			if (n < _size)
//			{
//				_size = n;
//				_str[_size] = '';
//			}
//			else
//			{
//				if (n > _capacity)
//				{
//					reserve(n);
//				}
//				for (size_t i = _size; i < n; ++i)
//				{
//					_str[i] = ch;
//				}
//				_size = n;
//				_str[_size] = '';
//			}
//		}
//		
//		//迭代器
//		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& insert(size_t pos, char ch)
//		{
//			assert(pos <= _size); //pos = _size相当于尾插
//			if (_size == _capacity)
//			{
//				reserve(_capacity == 0 ? 4 : _capacity * 2);
//			}
//			//size_t end = _size; 
//			//while (end >= pos)  //--end会造成负数,而--end是size_t类型
//			//{
//			//	_str[end + 1] = _str[end];
//			//	--end;
//			//}
//			解决1:强转类型
//			//int end = _size;
//			//while (end >=(int) pos)  //--end会造成负数,而--end是size_t类型
//			//{
//			//	_str[end + 1] = _str[end];
//			//	--end;
//			//}
//			//解决2:修改end位置
//			size_t end = _size+1;
//			while (end > pos)  //end等于0就停止
//			{
//				_str[end ] = _str[end-1];
//				--end;
//			}
//			_str[pos] = ch;
//			_size ++;
//			return *this;
//		}
//		//插入字符串
//		string& insert(size_t pos,const char* str)
//		{
//			assert(pos <= _size);
//			size_t len=strlen(str);
//			if (_size + len > _capacity)
//			{
//				reserve(_size + len);
//			}
//			size_t end = _size + len;
//			while (end > pos + len - 1) //或者while (end >= pos + len) ,但pos、len均为0就有问题
//			{
//				_str[end] = _str[end - len];
//				--end;
//			}
//			strncpy(_str + pos, str, len);  //不能使用strcpy
//			_size += len;
//			return *this;
//		}
//		//删除
//		string& erase(size_t pos, size_t len=npos)
//		{
//			assert(pos < _size);
//			if (len == npos || pos + len >= _size)
//			{
//				_str[pos] = '';
//				_size = pos;
//			}
//			else
//			{
//				size_t begin = pos + len;
//				while (begin <= _size)
//				{
//					_str[begin - len] = _str[begin];
//					++begin;
//				}
//				_size -= len;
//			}
//			return *this;
//		}
//		//查找字符
//		//The position of the first character of the first match.
//		//If no matches were found, the function returns string::npos.
//		size_t find(char ch,size_t pos=0)
//		{
//			for (; pos < _size; ++pos)
//			{
//				if (_str[pos] == ch)
//				{
//					return pos;
//				}
//			}
//			return npos;
//		}
//		//查找字符串
//		size_t find(const char*str, size_t pos = 0)
//		{
//			const char* p = strstr(_str + pos, str); //strstr暴力算法
//			if (p == nullptr)
//			{
//				return npos;
//			}
//			else
//			{
//				return p - _str;
//			}
//		}
//		void clear()
//		{
//			_str[0] = '';
//			_size = 0;
//		}
//	private:
//		char* _str;
//		size_t _size;     //有效字符个数,不包含
//		size_t _capacity; //实际存储的有效字符的空间
//		const static size_t npos;
//
//	};
//	//定义
//	const size_t string::npos = -1;
//	//这里不是成员函数,不在类里
//	//运算符<重载
//	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 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 !(s1 == s2);
//	}
//	//流运算符重载
//	ostream& operator<<(ostream& out, const string& s)
//	{
//		//out << s.c_str(); //无法打印不可见字符
//		for (auto ch : s)
//		{
//			out << ch;
//		}
//		return out;
//	}
//	istream& operator>>(istream& in,  string& s)
//	{
//		//s.clear();
//		//char ch;
//		in >> ch;
//		//ch = in.get();
//		//while (ch != ' ' && ch != 'n')
//		//{
//		//	s += ch;
//		//	//in >> ch;
//		//	ch = in.get();
//		//}
//		//return in;
//		//优化
//		s.clear();
//		char ch;
//		ch = in.get();
//		char buff[128] = { '' };
//		size_t i = 0;
//		while (ch != ' ' && ch != 'n')
//		{
//			buff[i++] = ch;
//			if (i == 127)
//			{
//				s += buff;
//				memset(buff, '', 128);
//				i = 0;
//			}
//			ch = in.get();
//		}
//		s += buff;
//		return in;
//	}
//	//getline
//
//}

//3.string完善的增删查改和使用的string(现代写法)
namespace my
{
	class string
	{
	public:
		构造函数
		//string(const char* str)
		//	:_size(strlen(str))
		//	,_capacity(_size)
		//{
		//	//要注意初始化顺序,取决于类的声明顺序
		//	_str = new char[_capacity + 1];
		//	//不能直接 _str=str; 因为会权限放大
		//	strcpy(_str, str);  //也拷贝了
		//}
		默认构造函数(无参使用的)
		//string()
		//	:_size(0)
		//	,_capacity(0)
		//{
		//	_str = new char[1];  //将_str初始化为空字符串,string库就是这种做法
		//	_str[0] = '0';
		//}

		//默认构造函数(全缺省版)
		string(const char* str = "") // ""、""均可以,''是字符
			:_size(strlen(str))
			, _capacity(_size)
		{
			//要注意初始化顺序,取决于类的声明顺序
			_str = new char[_capacity + 1];
			//不能直接 _str=str; 因为会权限放大
			strcpy(_str, str);  //也拷贝了
		}
		深拷贝函数版本1 s2(s1)
		//string(const string& s)
		//	:_str(new char[strlen(s._str) + 1])
		//{
		//	strcpy(_str, s._str);
		//}
		深拷贝函数版本2 s2(s1) //传统写法:本分实现,自劳
		//string(const string& s)
		//	:_size(strlen(s._str))
		//	, _capacity(_size)
		//{
		//	_str = new char[_capacity + 1];
		//	strcpy(_str, s._str);
		//}
		//深拷贝函数版本3 s2(s1) //现代写法:剥削行为,借他人之手,行私利,但简单
		//tmp去调用构造函数:s1->s2:构造函数->拷贝构造函数->构造函数->swap
		//tmp->s2
		void swap(string& s)
		{
			//库里的swap,可交换任意类型
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		string(const string& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			string tmp(s._str); //tmp是局部对象,出作用域会调用析构函数
			
			swap(tmp);
		}

		//析构函数
		~string()
		{
			if (_str)
			{
				delete[] _str;
			}
		}
		//s1=s3  ——>s1.operator=(&s1,s3)
		赋值重载函数--版本1 传统写法
		//string& operator = (const string& s)
		//{
		//	if (this != &s)  //解决s1=s1,自己释放自己的空间
		//	{
		//		//先保存,再开辟赋值
		//		char* tmp = new char[s._capacity + 1];
		//		strcpy(tmp, s._str);
		//		delete[] _str;
		//		_str = tmp;
		//		_size = s._size;
		//		_capacity = s._capacity;
		//	}
		//	return *this;
		//}
		赋值重载函数--版本2 现代写法
		//string& operator = (const string& s)
		//{
		//	if (this != &s)  //解决s1=s1,自己释放自己的空间
		//	{
		//		string tmp(s._str);
		//		swap(tmp);
		//	}
		//	return *this;
		//}
		赋值重载函数--版本3 现代写法
		string& operator = (string s) //传值传参,引用返回
		{
			swap(s);
			return *this;
		}
		//c_str是string中的一个函数,具体详见string文档
		//获取等效的字符串
		const char* c_str() const
		{
			return _str;
		}
		//重载[]
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		//重载[] const 提供两个版本的重载[] ,普通对象和const对象都可以调用
		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}
		//计算字符串大小
		//size_t size(const string* this)
		size_t size() const
		{
			return _size;
		}

		size_t capacity() const
		{
			return _capacity;
		}
		尾插数据
		//void push_back(char ch)
		//{
		//	if (_size == _capacity) //其实为_capacity开辟的多一个为存储的空间,但那个不参与比较
		//	{
		//		char* tmp = new char[_capacity * 2 + 1];
		//		strcpy(tmp, _str);
		//		delete[] _str;
		//		_str = tmp;
		//		_capacity *= 2;
		//	}
		//	_str[_size] = ch;
		//	++_size;
		//	_str[_size] = '';
		//}

		//尾插也可以使用+=(附用push_back)
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		//预留扩容
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}
		//尾插数据——附用reserve
		void push_back(char ch)
		{
			//if (_size == _capacity) //其实为_capacity开辟的多一个为存储的空间,但那个不参与比较
			//{
			//	//reserve( _capacity * 2);若_capacity为0,则出现bug
			//	reserve(_capacity==0 ? 4 : _capacity * 2);
			//}
			//_str[_size] = ch;
			//++_size;
			//_str[_size] = '';

			//附用insert
			insert(_size, ch);
		}
		//追加到字符
		void append(const char* str)
		{
			
			//附用insert
			insert(_size, str);
		}
		//尾插也可以使用+=(附用append)
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		//扩空间+初始化
		//删除部分数据,保留前n个
		void resize(size_t n, char ch = '')
		{
			//考虑到内存对齐,可能开辟的空间与n有些许微小出入
			if (n < _size)
			{
				_size = n;
				_str[_size] = '';
			}
			else
			{
				if (n > _capacity)
				{
					reserve(n);
				}
				for (size_t i = _size; i < n; ++i)
				{
					_str[i] = ch;
				}
				_size = n;
				_str[_size] = '';
			}
		}

		//迭代器
		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& insert(size_t pos, char ch)
		{
			assert(pos <= _size); //pos = _size相当于尾插
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			//size_t end = _size; 
			//while (end >= pos)  //--end会造成负数,而--end是size_t类型
			//{
			//	_str[end + 1] = _str[end];
			//	--end;
			//}
			解决1:强转类型
			//int end = _size;
			//while (end >=(int) pos)  //--end会造成负数,而--end是size_t类型
			//{
			//	_str[end + 1] = _str[end];
			//	--end;
			//}
			//解决2:修改end位置
			size_t end = _size + 1;
			while (end > pos)  //end等于0就停止
			{
				_str[end] = _str[end - 1];
				--end;
			}
			_str[pos] = ch;
			_size++;
			return *this;
		}
		//插入字符串
		string& insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			size_t end = _size + len;
			while (end > pos + len - 1) //或者while (end >= pos + len) ,但pos、len均为0就有问题
			{
				_str[end] = _str[end - len];
				--end;
			}
			strncpy(_str + pos, str, len);  //不能使用strcpy
			_size += len;
			return *this;
		}
		//删除
		string& erase(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos || pos + len >= _size)
			{
				_str[pos] = '';
				_size = pos;
			}
			else
			{
				size_t begin = pos + len;
				while (begin <= _size)
				{
					_str[begin - len] = _str[begin];
					++begin;
				}
				_size -= len;
			}
			return *this;
		}
		//查找字符
		//The position of the first character of the first match.
		//If no matches were found, the function returns string::npos.
		size_t find(char ch, size_t pos = 0)
		{
			for (; pos < _size; ++pos)
			{
				if (_str[pos] == ch)
				{
					return pos;
				}
			}
			return npos;
		}
		//查找字符串
		size_t find(const char* str, size_t pos = 0)
		{
			const char* p = strstr(_str + pos, str); //strstr暴力算法
			if (p == nullptr)
			{
				return npos;
			}
			else
			{
				return p - _str;
			}
		}
		void clear()
		{
			_str[0] = '';
			_size = 0;
		}
	private:
		char* _str;
		size_t _size;     //有效字符个数,不包含
		size_t _capacity; //实际存储的有效字符的空间
		const static size_t npos;

	};
	//定义
	const size_t string::npos = -1;
	//这里不是成员函数,不在类里
	//运算符<重载
	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 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 !(s1 == s2);
	}
	//流运算符重载
	ostream& operator<<(ostream& out, const string& s)
	{
		//out << s.c_str(); //无法打印不可见字符
		for (auto ch : s)
		{
			out << ch;
		}
		return out;
	}
	istream& operator>>(istream& in, string& s)
	{
		//s.clear();
		//char ch;
		in >> ch;
		//ch = in.get();
		//while (ch != ' ' && ch != 'n')
		//{
		//	s += ch;
		//	//in >> ch;
		//	ch = in.get();
		//}
		//return in;
		//优化
		s.clear();
		char ch;
		ch = in.get();
		char buff[128] = { '' };
		size_t i = 0;
		while (ch != ' ' && ch != 'n')
		{
			buff[i++] = ch;
			if (i == 127)
			{
				s += buff;
				memset(buff, '', 128);
				i = 0;
			}
			ch = in.get();
		}
		s += buff;
		return in;
	}
	//getline

}
//类型转换函数
//atoi C
//itoa C
//stoi C++11
//to_string 

(2)test.cpp:

#include "string.h"
//1.基本初始化测试
void TestString1()
{
	my::string s1("hello,world");
	cout << s1.c_str() << endl;
	//修改测试
	s1[0] = 'x';  //s1.operator[](0)='x';
	cout << s1.c_str() << endl;
	//读取测试
	for (size_t i = 0; i < s1.size(); ++i)
	{
		cout << s1[i] << " ";
	}
	cout << endl;
}
//2.浅拷贝及其问题测试
void TestString2()
{
	//浅拷贝带来的问题:
	//1.析构两次,程序崩溃 2.修改一个值,另一个也被改变
	my::string s1("hello,world");
	my::string s2(s1);  //调用拷贝构造函数
	cout << s1.c_str() << endl;
	cout << s2.c_str() << endl;
}
//3.深拷贝测试
void TestString3()
{
	//深拷贝:使得值相同,空间大小相同,但空间地址不同
	my::string s1("hello,world");
	my::string s2(s1);            //调用深拷贝构造函数
	cout << s1.c_str() << endl;
	cout << s2.c_str() << endl;

	s1[0] = 'x';
	cout << s1.c_str() << endl;
	cout << s2.c_str() << endl;
}
//4.赋值重载测试
void TestString4()
{
	//赋值面临的问题与浅拷贝相似
	my::string s1("hello,world");
	my::string s2(s1);              //调用深拷贝构造函数
	my::string s3("qqqqqqqqqq");
	s1 = s3;       //赋值

	cout << s1.c_str() << endl;
	cout << s2.c_str() << endl;
	cout << s3.c_str() << endl;
}
//int main()
//{
//	//TestString1();
//	//TestString2();
//	//TestString3();
//	TestString4();
//	//对于new的异常捕获
//	try
//	{
//		TestString4();
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	return 0;
//}

//5.增删查改测试
void TestString5()
{
	my::string s1("hello,world");
	cout << s1.c_str() << endl;
	my::string s2;  
	cout << s2.c_str() << endl;
}
//6.尾插测试+扩容测试
void TestString6()
{
	//my::string s1("hello,world");
	//cout << s1.c_str() << endl;
	使用push_back
	//s1.push_back('y');
	//cout << s1.c_str() << endl;
	//s1.push_back('y');
	//cout << s1.c_str() << endl;

	使用重载+= (附用push_back)
	//s1 += '6';
	//s1 += '7';
	//s1 += '8';
	//cout << s1.c_str() << endl;
	使用重载+= (附用reserve)
	//s1 += 'a';
	//s1 += 'b';
	//s1 += 'c';
	//cout << s1.c_str() << endl;

	//my::string s2; //reserve解决空串_capacity=0,再去_capacity*2仍为0
	//s2.reserve(20); //直接开辟指定空间
	
	//库里的string::resize
	std::string s3("cplusplus");
	s3.resize(20, 'x');
	s3.resize(5, 'x');

	cout << s3 << endl;

	//模拟实现的string::resize
	my::string s4("stringtest");
	s4.resize(5, 'y');
	s4.resize(15, 'g');
	cout << s4.c_str() << endl;
}

//7.遍历测试
void TestString7()
{
	my::string s1("hello,world");
	//方式1:下标+[]
	for (size_t i = 0; i < s1.size(); ++i)
	{
		s1[i] += 1;
		cout << s1[i] << " ";
	}
	cout << endl;
	//方式2:迭代器
	my::string::iterator it = s1.begin();
	while (it != s1.end())
	{
		*it -= 1;
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//方式3:范围for——底层被替换成迭代器访问
	for (auto& ch : s1)
	{
		cout << ch << " ";
		ch += 1;
	}
	cout << endl;
	for (auto ch : s1)
	{
		cout << ch << " ";
	}
	cout << endl;

}
//const对象权限测试
void  func(const my::string& s) //string的拷贝是深拷贝,使用引用减少拷贝
{
	//方式1:下标+[]
	for (size_t i = 0; i < s.size(); ++i)
	{
		//s[i] += 1; //这里传给const形参,不能写
		cout << s[i] << " ";
	}
	cout << endl;
	//方式2:迭代器
	my::string::const_iterator it = s.begin();
	while (it != s.end())
	{
		/
	my::string s4("hello,world");
	cin >> s4;
	cout << s4 << endl;

}
//12.赋值重载测试
void TestString12()
{
	my::string s1("hello,world");
	my::string s2(s1);
	cout << s2<< endl;
	my::string s3;
	s3 = s1;
	cout << s3 << endl;

}
//13.转换函数测试
void TestString13()
{
	int i;
	cin >> i;
	string s1 = to_string(i);  //to_string是库里的
	cout << s1 << endl;
	int val = stoi(s1);        //stoi是库里的
	cout << s1 << endl;

}

int main()
{
	
	//TestString1();
	//TestString2();
	//TestString3();
	//TestString4();
	//TestString5();
	//TestString6();
	//TestString7();
	//func("hello,world");
	//TestString8();
	//TestString9();
	//TestString10();
	//TestString11();
	//TestString12();
	TestString13();
	//对于new的异常捕获
	
	return 0;
}

后记:
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
                                                                    ——By 作者:新晓·故知

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1036735.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号