C++string类模拟实现

文章目录

      • 构造函数
        • 有参构造函数
        • 无参构造函数
        • 简略版本
        • 深拷贝和浅拷贝
      • 赋值重载
      • 析构函数
        • npos
        • c_str
        • 迭代器
        • reserve
        • push_back() && append()
        • []运算符
        • insert
        • erase
        • +=
        • find
        • cout,cin
        • 总结:
        • string.h 和测试代码

在前面我们学习string的功能,今天我们来模拟一下string类的实现。

构造函数

有参构造函数

在这里插入图片描述

string(const char *str)//(1)
			:_size(strlen(str)),//(2)
			_capacity(_size)//(3)
		{
			_str = new char[_capacity + 1];//(4)
			strcpy(_str, str);//(5)
		}

   ( 1 ) (1) (1)形参传递的字符串属于常量区,不能修改,const不能忘了
   ( 2 ) (2) (2)计算字符串的长度
   ( 3 ) (3) (3)初始化字符串容量_capacity
   ( 4 ) (4) (4)为字符指针开辟空间,这里需要多开一个字节,因为传进来的可能是个空串,空串含有一个'/0'(strlen计算到\0即停止,不含\0)。

------------------------------------------------------------我是分割线-----------------------------------------------------------

无参构造函数

在这里插入图片描述

	string()
			:_size(0),//(1)
			_capacity(0),//(2)
			_str(new char[1])//(3)
		{
			_str[0] = '\0';
		}

   ( 1 ) ( 2 ) (1)(2) (1)(2)因为传进来的是一个空串,所以_size_capacity都设置为0
   ( 3 ) (3) (3)空串有个/0,为其开一个字节空间。

简略版本

为了简略,上面的两种构造函数可以合成一个:

	string(const char*str="")//传进来的可能是空串 这里包含了无参和有参
			:_str(nullptr),
			_size(0),
			_capacity(0)
		{
			int newcapacity = strlen(str);//(1)
			_str = new char[newcapacity + 1];//(2)
			strcpy(_str, str);//(3)
			_size = newcapacity;//(4)
			_capacity = newcapacity;//(5)
			
		}

   ( 1 ) (1) (1)计算形参字符串的长度
   ( 2 ) (2) (2)申请空间
   ( 3 ) (3) (3)拷贝字符串的数据
   ( 4 ) (4) (4)更新_size
   ( 5 ) (5) (5)更新_capacity
------------------------------------------------------------我是分割线-----------------------------------------------------------

深拷贝和浅拷贝

在模拟拷贝构造函数之前,我们首先学习一下深拷贝和浅拷贝。

浅拷贝:计算机默认提供的拷贝构造函数和赋值重载函数实现的都是浅拷贝,浅拷贝完成的字节序的拷贝。举例说明:浅拷贝就是抄作业,连名字也一起照抄的一种行为。
这种不修改的名字的抄作业行为有时候就容易被老师发现,然后被逮住。
在计算机中也是如此:
浅拷贝带来的问题就是总结就是:堆区申请的内存被重复释放
浅拷贝的问题需要通过人为深拷贝进行解决。

C++string类模拟实现_第1张图片
解决方法如下:
C++string类模拟实现_第2张图片
在了解了深浅拷贝以后,我们继续学习拷贝构造函数的实现:
在这里插入图片描述
拷贝构造函数的传统写法:自己开空间,完成深拷贝

string(const string &s)//拷贝构造
			:_size(s._size)//(1)
			_capacity(s._capacity),//(2)
			_str(nullptr)
		{
			//reserve(_capacity); !!!!拷贝构造这里不能使用reserve ,因为strcpy会解引用空指针
			_str = new char[_capacity+1];//(3)
			strcpy(_str, s._str);//(4)
		}

注意:这里的拷贝构造不能用reserve开空间,指针_str是一个空指针,而strcpy需要传入空指针,系统会报错,所以需要通过new申请空间。
   ( 1 ) ( 2 ) (1)(2) (1)(2)拷贝_size_capacity
   ( 3 ) (3) (3)进行深拷贝,在堆区重新申请一块空间,字符串末尾有个'\0'所以需要多开一个空间。
   ( 4 ) (4) (4)将数据拷贝到新空间。

拷贝构造函数的现代写法:复用string的有参构造函数

void swap(string &s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
	string(const string &s)
			:_size(0),
			_capacity(0),
			_str(nullptr)
		{
			string tmp(s._str);//复用有参构造函数
			swap(tmp);
			
		}

------------------------------------------------------------我是分割线-----------------------------------------------------------

赋值重载

赋值重载的传统写法:老老实实进行开空间,深拷贝

string& operator=(string &s) {

			if (this!=&s)//(1)
			{
				char *temp = new char[s._capacity + 1];//(2)
				strcpy(temp, s._str);//(3)
				delete []_str;//(4)
				_size = s._size;//(5)
				_capacity = s._capacity;//(6)
				_str = temp;//(7)
			}
			return *this;
		}

   ( 1 ) (1) (1)赋值重载的时候,可能会有这样一种情况s1 = s1,对于这种自己给自己赋值的情况,直接进行返回。
   ( 2 ) (2) (2) 在进行深拷贝的时候,先进行申请空间,因为申请空间可能会失败。
   ( 3 ) (3) (3)将数据拷贝到临时对象中。
   ( 4 ) (4) (4)赋值重载对象可能先前就指向了一块空间,需要将这块空间进行释放。
C++string类模拟实现_第3张图片
   ( 5 ) (5) (5)拷贝临时对象的_size_capacity
   ( 6 ) (6) (6)_str指针指向临时对象中申请的空间

------------------------------------------------------------我是分割线-----------------------------------------------------------

赋值重载的现代写法:复用拷贝构造函数

void swap(string &s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

string& operator=(string s)//(1)
		{
			if (this != &s)
			{
				
				swap(s);//(2)
			}
			return  *this;
		}

   ( 1 ) (1) (1):赋值重载运算符的现代写法精髓正是在这,因为形参是实参的拷贝,所以这里会先调用拷贝构造函数完成深拷贝。
   ( 2 ) (2) (2):防止s1=s1这种自己给自己赋值的情况,直接将拷贝构造得到的对象和该对象交换。

析构函数

~string()
		{
			delete[]_str;
			_str = nullptr;
			_size = _capacity = 0;
		}

析构函数的实现很简单,释放空间就好。

------------------------------------------------------------我是分割线-----------------------------------------------------------

npos

string::npos是一个静态成员常量,表示size_t的最大值(Maximum value for size_t)。在使用中通常将其定义为-1。

c_str

const char* c_str() const
		{
			return _str;//(1)
		}

   ( 1 ) (1) (1)返回字符指针。

迭代器

	typedef char* iterator;//(1)
	typedef const char* const_iterator;//(2)

		iterator begin() {//(3)
			return _str;
		}

		iterator end()//(4)
		{
			return _str + _size;
		}

		const_iterator begin()  const
		{
			return _str;
		}

		const_iterator end() const
		{
			return _str + _size;
		}

   ( 1 ) ( 2 ) (1)(2) (1)(2)迭代器又分为普通迭代器const迭代器,这里对两个返回值进行typedef
   ( 3 ) (3) (3)返回字符的第一个位置
   ( 4 ) (4) (4)返回最后一个字符的下一个位置

------------------------------------------------------------我是分割线-----------------------------------------------------------

reserve

void reserve(int newcapacity)
		{
			char *tmp = new char[newcapacity + 1];//(1)
			strcpy(tmp, _str);//(2)
			delete []_str;//(3)
			_str = tmp;//(4)
			_capacity = newcapacity;//(5)

		}

   ( 1 ) (1) (1)申请新空间。
   ( 2 ) (2) (2)将旧空间的数据拷贝到新空间。
   ( 3 ) (3) (3)将旧空间的数据释放。
   ( 4 ) (4) (4)让指针指向新空间。
   ( 5 ) (5) (5)更新_capacity

push_back() && append()

   ( 1 ) (1) (1)push_back()

void push_back(char ch)
		{
			if (_size == _capacity)//(1)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);//(2)
			}
			_str[_size++] = ch;//(3)
			_str[_size] = '\0';//(4)
		}

   ( 1 ) (1) (1)说明空间用完了,需要扩容
   ( 1 ) (1) (1)如果原空间为0,就扩容为4,反之扩大2倍
   ( 1 ) (1) (1)尾插字符
   ( 1 ) (1) (1)别忘了'\0'

   ( 1 ) (1) (1)append()

void append(const char *str)
		{
			int len = strlen(str);//(1)
			int newcapacity = len + _size;//(2)
			if (newcapacity >= _capacity)//(3)
			{
				reserve(newcapacity + 1);
			}
			memcpy(_str + _size, str, len);//(4)
			_size = newcapacity;//(5)
			_capacity = newcapacity ;//(6)
			_str[_size] = '\0';//(7)
		}

   ( 1 ) (1) (1)计算要插入的字符串的长度。
   ( 2 ) (2) (2)计算当前所需要的空间容量。
   ( 3 ) (3) (3)当前容量如果不够,就进行扩容。
   ( 4 ) (4) (4)将字符串插入。
   ( 5 ) ( 6 ) (5)(6) (5)(6)更新_size_capacity
   ( 7 ) (7) (7)别忘了末尾还有个'\0'

------------------------------------------------------------我是分割线-----------------------------------------------------------

[]运算符

   ( 1 ) (1) (1)普通版本

	char& operator[](int pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

   ( 1 ) (1) (1)const版本

	
		const char& operator[](int pos)const
		{
			assert(pos < _size);
			return _str[pos];
		}

ps::这里返回的时候别忘了+引用[]需要支持读写操作
两个版本的实现基本相同,const版本返回值是const的,只能读但是不能写。
------------------------------------------------------------我是分割线-----------------------------------------------------------

insert

   ( 1 ) (1) (1)insert插入字符

void insert(int pos,char ch)
		{
			assert(pos <= _size);
			if (_size == _capacity)
				reserve(_capacity == 0 ? 4 : _capacity * 2);//(1)
			int l = pos;
			int r = _size;
			while (l < r)//(2)
			{
				_str[r] = _str[r - 1];
				r--;
			}
			_str[pos] = ch;//(3)
			_str[++_size] = '\0';//(4)
		}

   ( 1 ) (1) (1)如果容量不够,就进行扩容。
   ( 2 ) (2) (2)插入字符需要挪动数据,从最后一个位置开始挪动。
   ( 3 ) (3) (3)将要插入的位置赋值。
   ( 4 ) (4) (4)更新_size,并且末尾添上\0

   ( 2 ) (2) (2)insert插入字符串

string& insert(int pos, const char *str)//插入字符串
		{
			//判断容量够不够
			int len = strlen(str);//(1)
			if (len + _size > _capacity)//(2)
				reserve(len + _size);

			int l = pos;
			int r = _size + len;
			while (l+len-1 < r)//(3)
			{
				_str[r] = _str[r - len];
				r--;
			}
			strncpy(_str + pos, str, len);//(4)
			_size += len;//(5)
			return *this;
			

		}

   ( 1 ) (1) (1)计算要插入的字符串的长度。
   ( 2 ) (2) (2)判断是否需要扩容。
   ( 3 ) (3) (3)挪动数据。
   ( 4 ) (4) (4)将要插入的字符串插入。
   ( 5 ) (5) (5)更新_size

------------------------------------------------------------我是分割线-----------------------------------------------------------

erase

string&	erase(int pos = 0, int len = npos)
		{
			assert(pos < _size);

			if (len == npos || pos+len >= _size)//(1)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);//(2)
				_size -= len;
			}

			return *this;
		}

   ( 1 ) (1) (1):判断是否需要删除pos位置开始的所有字符。
   ( 2 ) (2) (2),将数据拷贝到被删除的位置。这里我们进行画图理解。
C++string类模拟实现_第4张图片

+=

   ( 1 ) (1) (1)+=字符串

string& operator+=(const char *str)
		{
			append(str);//(1)
			return *this;
		}

   ( 1 ) (1) (1)复用append函数。

   ( 1 ) (1) (1)+=字符

		string& operator+=(char ch)
		{
			push_back(ch);//(1)
			return *this;
		}

   ( 1 ) (1) (1)复用push_back函数。

------------------------------------------------------------我是分割线-----------------------------------------------------------

find

   ( 1 ) (1) (1)查找字符第一次出现的位置

	int find(char ch,int pos=0)
		{
			for (int i = pos; i < _size; i++)//(1)
			{
				if (_str[i] == ch)
					return i;
			}
			return -1;
		}

   ( 1 ) (1) (1)对字符串遍历一遍,如果找到了就返回该字符对应位置
   ( 2 ) (2) (2)没找到就返回-1
在这里插入图片描述

   ( 2 ) (2) (2)查找字符串第一次出现的位置

int find(const char* s, int pos = 0)
		{
			const char* ptr = strstr(_str + pos, s);//(1)
			//出现的位置,没找到返回空指针。
			if (ptr == nullptr)
			{
				return npos;
			}
			else
			{
				return ptr - _str;//(2)
			}
		}

   ( 1 ) (1) (1)使用strstr库函数进行查找字串,如果没找到,返回-1
   ( 2 ) (2) (2)这里涉及指针-指针,我们进行画图理解:
C++string类模拟实现_第5张图片

cout,cin

cout

ostream& operator<<(ostream&cout, string &s)
	{
		//cout << s.c_str() << endl;//不能这样写 因为cout判断结束是遇到'\0',但是如果字符串中插入'\0',
		//就会导致后面的字符打印不出来
		for (int i = 0; i < s._size; i++)
			cout << s[i];
		return cout;
	}

cin

istream& operator>>(istream& in, string& s)
	{
		s.clear();//(1)

		char ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch = in.get();//(2)
		}

		return in;
	}

   ( 1 ) (1) (1)在输入字符串之前必须先clear一次,字符串在先前可能有字符存在
   ( 2 ) (2) (2)cin.get(),每次读取一个字符。

总结:

   ( 1 ) (1) (1):使用strcpy函数时要注意实参是不是一个可以使用的地址,并且不能为空。
   ( 2 ) (2) (2):临时对象的生命周期到函数结束,接着会被析构掉。
   ( 3 ) (3) (3):指针-指针得到的是两个指针的间隔长度。
如:
C++string类模拟实现_第6张图片

   ( 4 ) (4) (4):reserve每次都会多开一个空间,用来存储‘\0’

   ( 5 ) (5) (5):字符串属于常量区,形参接收的时候需要加const
   ( 6 ) (6) (6):重载[]运算符的时候需要+引用,因为需要[]运算符需要支持读写操作
   ( 7 ) (7) (7):insert,find,erase这里的对于库函数的用法很灵活,需要多练习。

string.h 和测试代码

#pragma once
#include
#include
using namespace std;
#include


namespace m_string {
	class string {
	public:
		typedef char * iterator;
		typedef const  char* const_iterator;//const 迭代器就是字符串的内容只能读不能写


		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;//因为end指向所以数据的下一个位置,所以直接+size就好了
		}
		const_iterator begin()const//const迭代器const对象进行调用,后面的const修饰的是this指针,也就是类的成员不能修改
		{
			return _str;
		}
		const_iterator end()const
		{
			return _str + _size;
		}

		string(const char*str="")//传进来的可能是空串 这里包含了无参和有参
			:_str(nullptr),
			_size(0),
			_capacity(0)
		{
			int newcapacity = strlen(str);
			_str = new char[newcapacity + 1];
			strcpy(_str, str);
			_size = newcapacity;
			_capacity = newcapacity;
			
		}
		char* c_str()
		{
			return _str;
		}
		
		int capacity()
		{
			return _capacity;
		}

		int size()
		{

			return _size;
		}

		void reserve(int newcapacity)
		{
			char *tmp = new char[newcapacity + 1];
			strcpy(tmp, _str);
			delete []_str;
			_str = tmp;
			_capacity = newcapacity;

		}

		void push_back(char ch)//尾插字符
		{
			//需要判断是否需要扩容
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			_str[_size++] = ch;
			_str[_size] = '\0';

		}
		
		~string()
		{
			delete []_str;
			_size = _capacity = 0;
		}

		void swap(string &s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		//传统写法!!!!!!!
		//string(const string &s)//拷贝构造
		//	:_size(s._size),
		//	_capacity(s._capacity),
		//	_str(nullptr)
		//{
		//	//reserve(_capacity); !!!!拷贝构造这里不能使用reserve ,因为strcpy会解引用空指针
		//	_str = new char[_capacity+1];
		//	strcpy(_str, s._str);
		//}

	

		//现代写法
		string(const string &s)
			:_size(0),
			_capacity(0),
			_str(nullptr)
		{
			string tmp(s._str);//复用有参构造函数
			swap(tmp);
			
		}
		//-----------------------------------------------------------------
		//operator=传统写法
		//string& operator=(string &s) {

		//	if (this != &s)//(1)
		//	{
		//		char *temp = new char[s._capacity + 1];//(2)
		//		strcpy(temp, s._str);//(3)
		//		delete[]_str;//(4)
		//		_size = s._size;//(5)
		//		_capacity = s._capacity;//(6)
		//		_str = temp;//(7)
		//	}
		//	return *this;
		//}

		string& operator=(string s)
		{
			if (this != &s)
			{
				
				swap(s);
			}
			return  *this;
		}

		
		void resize(int newcapacity,char ch='\0')
		{
			//开的空间大于原空间
			if (newcapacity >= _capacity)
			{
				reserve(newcapacity);
				memset(_str + _size, ch, newcapacity - _size);
				_capacity = newcapacity;
			}
				
			else if (newcapacity < _capacity)
			{
				_str[newcapacity] = '\0';
				_size = newcapacity;
			}
			
		}

		char operator[](int x)
		{
			assert(x < _size);
			return _str[x];
			
		}
		const char& operator[](int x)const
		{
			assert(x < _size);
			return _str[x];
		}

		void insert(int pos,char ch)
		{
			assert(pos <= _size);
			if (_size == _capacity)
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			int l = pos;
			int r = _size;
			while (l < r)
			{
				_str[r] = _str[r - 1];
				r--;
			}
			
			_str[pos] = ch;
			_str[++_size] = '\0';
		}


		string& insert(int pos, const char *str)//插入字符串
		{
			//判断容量够不够
			int len = strlen(str);
			if (len + _size > _capacity)
				reserve(len + _size);

			int l = pos;
			int r = _size + len;
			while (l+len-1 < r)
			{
				_str[r] = _str[r - len];
				r--;
			}
			cout << _str << endl;
		
			strncpy(_str + pos, str, len);
			_size += len;
			return *this;
			

		}

		int find(char ch,int pos=0)
		{
			for (int i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
					return i;
			}
			return -1;
		}

		int find(const char* s, int pos = 0)
		{
			const char* ptr = strstr(_str + pos, s);//找到了就返回子串在主串中第一次
			//出现的位置,没找到返回空指针。
			if (ptr == nullptr)
			{
				return npos;
			}
			else
			{
				return ptr - _str;
			}
		}
		
		string &operator+=(char ch)
		{
			if (_size == _capacity)
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			push_back(ch);
			return *this;
		}
		char *_str;
		int _size;
		int _capacity;
		static const size_t npos = -1;

		void append(const char *str)
		{
			int len = strlen(str);
			int newcapacity = len + _size;
			if (newcapacity >= _capacity)
			{
				reserve(newcapacity + 1);
			}
			memcpy(_str + _size, str, len);
			_size = newcapacity;
			_str[_size] = '\0';
			_capacity = newcapacity ;
			
		}

		string&	erase(int pos = 0, int len = npos)
		{
			assert(pos < _size);

			if (len == npos || pos + len >= _size)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				cout << (_str + pos) << endl;
				cout << (_str + pos + len) << endl;
				_size -= len;
			}

			return *this;
		}

		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}

	};
	ostream& operator<<(ostream&cout, string &s)
	{
		//cout << s.c_str() << endl;//不能这样写 因为cout判断结束是遇到'\0',但是如果字符串中插入'\0',
		//就会导致后面的字符打印不出来
		for (int i = 0; i < s._size; i++)
			cout << s[i];
		return cout;
	}

	istream& operator>>(istream& in, string& s)
	{
		s.clear();

		char ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch = in.get();
		}

		return in;
	}
	

	void test1()//测试有参和无参 ok!
	{
		//测试无参
		/*string s1;
		cout << s1.c_str() << endl;
		cout << s1.capacity() << endl;
		cout << s1.size() << endl;*/

		//测试有参
	/*	string s2("hello");
		cout << s2.c_str() << endl;
		cout << s2.capacity() << endl;
		cout << s2.size() << endl;*/

		//测试有参空串
		/*string s3("");
		cout << s3.c_str() << endl;
		cout << s3.capacity() << endl;
		cout << s3.size() << endl;*/
	}
	void test2()//测试迭代器
	{
		//测试普通迭代器+无参
		/*string s1;
		string::iterator it = s1.begin();
		while (it!=s1.end())
		{
			cout << *it<<" ";
			it++;
		}*/

		//测试普通迭代器+有参
		/*string s2("helloddddddddddddd");
		string::iterator it = s2.begin();
		while (it != s2.end())
		{
			cout << *it << " ";
			it++;
		}*/

		//测试const迭代器+
		/*const string s2("helloc");
		string::const_iterator it = s2.begin();
		while (it != s2.end())
		{
			cout << *it << " ";
			it++;
		}*/
	}
	void test3()//测试push_Back 和reserve
	{
		//测试能否正常扩容和插入
		/*string s1;
		s1.push_back(1);
		s1.push_back(2);
		s1.push_back(3);
		s1.push_back(4);
		cout << s1.size() << endl;
		cout << s1.capacity() << endl;*/
		//前4个容量为4,插入第五个以后容量变为8
	/*	s1.push_back(5);
		cout << s1.size() << endl;
		cout << s1.capacity() << endl;*/

		//测试能否搭配迭代器进行使用
		/*string s2("h");
		s2.push_back('e');
		s2.push_back('l');
		s2.push_back('l');
		s2.push_back('o');
		for (auto ch : s2)
			cout << ch;*/



	}
	void test4()//测试拷贝构造
	{
		string s1("hello");
		string s2(s1);
		for (auto ch : s2)
			cout << ch;
	

		
	}
	void test5()//测试赋值重置运算符
	{
		string s1("hello");
		string s2("hellooooo");
		s2 = s1;
		cout << s2.size() << endl;
		cout << s2.capacity() << endl;
	}
	void test6()//测试resize
	{
		//string s1("aaaaa");//原空间大于要申请的空间
		//s1.resize(1);
		//for (auto ch : s1)
		//	cout << ch;

		string s2("aaaa");//原空间小于要申请的空间
		s2.resize(10);
		for (auto ch : s2)
			cout << ch;
		cout << s2.capacity() << endl;
	}
	void test7()//测试[]
	{
		string s1("hello");
		cout << s1[0] << endl;
		cout << s1[1] << endl;
		cout << s1[2] << endl;
		cout << s1[3] << endl;
		cout << s1[4] << endl;
		cout << s1[5] << endl;//越界,断言程序崩溃

	}
	void test8()//+=
	{
		string s1;
		s1 += 'a';
		cout << s1.c_str() << endl;
	}
	void test9()//append
	{
		string s1("aaa");
		s1.append("h");
		cout << s1.c_str() << endl;
	}
	void test10()//cout 和cin
	{
		string s1("hello dasdasd");
		cin >> s1;
		cout << s1 << endl;
	}
	void test11()//insert
	{
		string s1("hello");
		s1.insert(1, "adc");
		cout << s1.c_str() << endl;

	}
	void test12()//find
	{
		//查找单个字符
		string s1("hello");
		cout << s1.find("llo");

		//查找字符串

	}
	void test13()//erase
	{
		string s1("hello");
		s1.erase(2,2);
		cout << s1.c_str() << endl;
	}
	
	void test14()//测试现代写法的拷贝构造
	{
		string s1("hello");
		string s2(s1);
		cout << s2 << endl;
		cout << s2.size() << endl;
		cout << s2.capacity() << endl;
	}
	void test15()//测试operator现代写法
	{
		string s1("dasd");
		string s2=s1;
		
		cout << s2 << endl;
		cout << s2.capacity() << endl;
		cout << s1.size() << endl;
	}

}

你可能感兴趣的:(C++,c++)