【c++】string模拟实现

string类的接口

namespace zjw
{
	class string
	{public:
		typedef char* iterator;
		typedef   const char* const_iterator;
	private:
		char* _str;
		int _size;
		int _capacity;



	};

这里的迭代器直接使用原生指针来封装。
_str为指向string数组的首地址的指针。
_size为string数组的大小。
_capacity为string数组的容量

基本函数

实现 函数返回string的首地址;
实现 函数返回string的尾地址;
实现 函数返回string的大小;
实现 函数返回string的容量;

	iterator begin()
		{
			return _str;
		
		
		
		}
	iterator end()
		{
			return _str+_size;



		}
	size_t size()
		{
			return _size;
		
		
		
		
		}
	size_t capacity()
		{
			return _capacity;

		
		}

如果一个string类不能被修改的话,就无法调用非const的成员函数
在这里插入图片描述

	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()
		{ 
			delete[]_str;
			_str = nullptr;
			_size = _capacity = 0;

		
		
		
		
		}

这里有一个问题,就是默认构造传的缺省参数可以是nullptr 吗??
答案是不行的,因为strlen要将str解引用找’\0’,如果传nullptr的话,对空指针解引用就会出错。
这里也不可以传单字符‘\0’,因为这里的str是const char* 类型,而’\0’是char 类型


运算符重载下标访问函数

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

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



		}

下标为_size的地方存的是’\0’,所以不用访问,pos<_size,为了让const迭代器不修改对于下标的值,修改上面得到下面,对上面进行函数重载

reserve函数

	void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[]_str;
				_str = tmp;
				_capacity = n;

			}
		
		
		
		
		
		}

在这里插入图片描述
注意:这里多开一个是为了存’\0’;

push_back()函数

	void push_back(char ch)
		{
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);

			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';


		
		
		
		
		}

原来下标是_size的地方是‘\0’,然后之间在_size的地方放入ch,_size++,染后在补一个’\0’;要插入数据的一半都要扩容

append函数

	void append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);

			}
			strcpy(_str + _size, str);
			_size += len;
			//_str[_size] = '\0';

		}

尾插一个字符串,如果string的大小+要插入的字符串大小>_capacity,就扩容到_size + len,刚好,strcpy会从str开始直到遇到‘\0’一个字节一个字节拷贝到_str + _size(原字符串’\0’的地方),这里会把str字符串后面的‘\0’也拷贝过来。

运算符重载+=字符以及+=字符串

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

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

		



		}

在这里传引用返回是因为_str指向的空间是在堆上开的,出函数不会被销毁,所以可以传引用返回

insert函数(插入字符)

void insert(size_t pos, char ch)
		{
			assert(pos<=_size);
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);

			}
			size_t end = _size;
			while (end >=pos)
			{

				_str[end+1] = _str[end];
				end--;


			}
			_str[pos] = ch;
			_size++;

		
		
		
		
		
		}

上面这个写法可以吗??
是不可以的
在这里插入图片描述
怎么修改呢??

	void insert(size_t pos, char ch)
		{
			assert(pos<=_size);
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);

			}
			size_t end = _size+1;
			while (end >pos)
			{

				_str[end] = _str[end-1];
				end--;


			}
			_str[pos] = ch;
			_size++;

		
		
		
		
		
		}

这样就可以了,我们从’\0’的下一个位置开始end,此时end结束的条件是=0,所以不会陷入循环,这里和顺序表的insert很像,可以参考顺序表那里。


earse函数

	void earse(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos || pos > _size-len)
			{
				_str[pos] = '\0';
				_size = pos;
				

			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;

			}
			
		
		
		
		
		
		
		}

删除从pos位置开始的len个字符长度的字符,如果len大于剩下的字符,就全删了,这里给的缺省值为npos=-1,可以认为是很大的数,绝对超过了pos后面的字符数,我们要在string里面声明一个npos,在类外面定义初始化。
在这里插入图片描述

如果len==npos或者len+pos>_size,就始要将pos开始后面的字符串全删除,我们直接在pos位置放’\0’即可,
_size=pos;
如果没有超过字符串
在这里插入图片描述


insert(插入字符串)

void insert(size_t pos, const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);

			}
			size_t end = _size + len;
			while (end > pos + len - 1)
			{
				_str[end] = _str[end - len];
				end--;

			}
			strncpy(_str + pos, str, len);
			_size += len;


		}

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9d88ba8502954c0dbd884890654c612a.png

void test6()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.insert(2, "hello");
		cout << str.c_str();




	}

swap

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

}
	void test12()
	{   string str1;
		string str2;
		str1 += "hello";
		str2+="nihao";
		cout << "str1:"<<str1 << endl;
		cout << "str2:"<<str2 << endl;
		str1.swap(str2);
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;

	}

在这里插入图片描述


这里我们自己实现的swap是类成员函数,但是#include< algorithm >这个头文件库里面也有一个swap,swap全局也有一个非成员函数swap

在这里插入图片描述

我们可以发现算法库中的swap需要完成三次的拷贝,以及一次析构(临时变量c的析构),而string里面定义一个全局的swap,就是为了防止调用算法库里面的swap,因为会先在全局找,然后会在展开的库里找,而全局的swap实现只需要调用类里面的swap即可

	void swap(string& x, string& y)
	{
		x.swap(y);
		cout << "没使用库里的" << endl;
	
	}
	void test13()
	{
		string str1;
		string str2;
		str1 += "hello";
		str2 += "nihao";
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;
		swap(str1, str2);//检测是调用库里的,还是全局的
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;
	
	
	}

在这里插入图片描述

赋值以及拷贝构造

	string(const string& s)
		{
			string tmp(s._str);
			swap(tmp);
		
		
		
		
		}
		string& operator=(string tmp)
		{
			swap(tmp);
			return *this;
		}

根据调试发现
在这里插入图片描述

老版本赋值

		string& operator=(const string& s)
		{
			char* tmp = new char[s._capacity + 1];
			strcpy(tmp, s._str);
			delete[] _str;
			_str = tmp;
			_size = s._size;
			_capacity = s._capacity;
			return *this;

			




			

		}

find函数(查找字符)

	size_t find(char ch, size_t pos = 0)
		{

			for (int i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
					return i;



			}
			return npos;





		}

从pos位置开始查找,如果pos使用缺省,则从第一个位置开始查找,从pos位置开始遍历,如果找到返回下标,如果找不到返回npos

	void test7()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.insert(2, "hello");
		cout << endl;
		int ret = str.find('b', 0);
		cout << ret;


	}

在这里插入图片描述


find函数(查找子串)

		size_t find(const char* sub, size_t pos = 0) const
		{
			assert(pos < _size);//下标为_size的是‘\0’
			const char* ptr = strstr(_str + pos, sub);
			if (ptr != nullptr)//找到了,但是strstr返回的是找到子串的起始地址-字符串起始地址就是子串相对起始位置的长度
			{
				return ptr - _str;

			}
			else
			{
				return npos;
			}





		}
	void test8()
	{
		string str;
		str += "beijing huanyingni zhangjiawang";
		int ret = str.find("zhangjiawang");
		cout << ret;




	}

在这里插入图片描述


substr函数

string substr(size_t pos = 0, size_t len = npos) const
		{
			string substr;

			if (pos > _size - len)
			{
				for (int i = pos; i <= _size; i++)
				{
					substr += _str[i];
				}


			}
			else
			{

				for (int i = pos; i < pos + len; i++)
				{
					substr += _str[i];
				}
				substr += '\0';

			}
			return substr;





		}

从pos位置开始取,取len个长度,分两种情况,如果从pos开始还没取到len长,就结束,就取到结尾,遍历pos到_size,string substr 保存遍历的值.
第二种,遍历pos到pos+len,string substr 保存遍历的值.最后记得加‘\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 strcmp(s1.c_str(), s2.c_str());



	}
	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);



	}

注意这里为什么要搞成全局的呢??

	void test10()
	{
		string str1;
		string str2;
		str1 += "abc";
		str2 += "aba";

		cout << (str1 == str2) << endl;
		cout << ("aba" == str2) << endl;//2
		cout << (str2== "aba") << endl;




	}

因为第二种的话不满足类成员做左操作数,全局的话就可以,而第三个是会搞一个类型转换.

	void test10()
	{
		string str1;
		string str2;
		str1 += "abc";
		str2 += "aba";

		cout << (str1 == str2) << endl;
		cout << ("aba" == str2) << endl;
		cout << (str2== "aba") << endl;
		 cout << (str1>str2) << endl;
		 cout << (str1 >=str2) << endl;
		 cout << (str1<str2) << endl;
		 cout << (str1 <=str2) << endl;
		 cout << (str1!=str2) << endl;




	}

在这里插入图片描述


运算符重载流插入

	ostream& operator<<(ostream& out, const string& s)
	{
		for (auto e : s)//遍历一个一个输出
		{
			out << e;
		}
		return out;






	}

有返回值是为了可以连续流插入

运算符重载流提取

版本一:

	istream& operator>>(istream& in, string& s)
	{
		
		char ch;

		
		in >> ch;//读取字符到ch
		while (ch != ' ' && ch != '\n')//读到‘ ’或‘\n’结束输入
		{s += ch;//将ch加进去
	    in >> ch;//循环读取


		}
		
return in;




	}

这样写会有一个问题,就是cin和scanf一样默认‘\n’和‘ ’是分割符不会进行读取,所以ch不会是空格或换行,所以陷入死循环.
在这里插入图片描述
版本2:
c语言中可以用getchar来读取,而c++中存在get就可以读空格

istream& operator>>(istream& in, string& s)
	{
		
		char ch;

		
		in.get(ch);
		
		
		while (ch != ' ' && ch != '\n')
		{

		
		
			s += ch;
			in.get(ch);


		}
		
			
			
		

		return in;




	}
	void test11()
	{
		string str1;
		string str2;
		cin >> str1;//>>str2;//>>str2;
		cout << str1;
		//cout << str1.capacity();




	}

在这里插入图片描述


版本3
由于我们在s+=ch,会出现频繁扩容,影响效率,我们应该怎么解决呢??
我们可以提前开好空间,但是不知道应该开多大.假如说我们开128个

	istream& operator>>(istream& in, string& s)
	{
		
		char ch;

		
		in.get(ch);
		
		s.reserve(128);

		while (ch != ' ' && ch != '\n')
		{

		
		
			s += ch;
			in.get(ch);


		}
		
			
			
		

		return in;




	}
	void test11()
	{
		string str1;
		string str2;
		cin >> str1;//>>str2;//>>str2;
		//cout << str1;
		cout << str1.capacity();




	}

在这里插入图片描述
两个数据开128就会有极大的浪费,多一点还好
在这里插入图片描述
版本4

	istream& operator>>(istream& in, string& s)
	{
		s.clear();//可能我们s里面之前有数据,但是流提取是要覆盖的

		char ch;

		ch = in.get();
		
		char buff[128];
		int i = 0;
		while (ch != ' ' && ch != '\n')
		{

			buff[i++] = ch;
			if (i == 127)
			{
				buff[127] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();


		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}

		return in;




	}

这里感觉可以类比冯诺依曼体系,buff就相当于内存,先将输入的值放在内存buff里面,等到装满了,在一次性给s,减少搬运次数.避免了一次空间开的很大,而数据只有几个
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

clear

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

		}

c_str

将const string* 转化为const char*

	const char* c_str() const
		{
			return _str;



		}

cout不能直接处理自定义类型string,但是可以使用c_str将string转成常量字符串,内置类型就可以直接打印


源码

.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#include<assert.h>
#include<iostream>
#include<algorithm>
namespace zjw
{
	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()
		{
			delete[]_str;
			_str = nullptr;
			_size = _capacity = 0;





		}
		size_t size()
		{
			return _size;




		}
		size_t capacity()
		{
			return _capacity;


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



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



		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[]_str;
				_str = tmp;
				_capacity = n;

			}





		}
		void push_back(char ch)
		{
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);

			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';






		}
		void append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);

			}
			strcpy(_str + _size, str);
			_size += len;
			//_str[_size] = '\0';

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



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





		}
		void insert(size_t pos, char ch)
		{
			assert(pos <= _size);
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);

			}
			size_t end = _size + 1;
			while (end > pos)
			{

				_str[end] = _str[end - 1];
				end--;


			}
			_str[pos] = ch;
			_size++;






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



		}
		void earse(size_t pos, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos || pos > _size - len)
			{
				_str[pos] = '\0';
				_size = pos;


			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;

			}







		}
		bool empty()
		{

			return _size == 0;

		}
		void resize(size_t n, char ch = '\0')
		{

			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;

			}
			else
			{
				reserve(n);
				for (size_t i = _size; i < n; i++)
				{
					_str[i] = ch;

				}
				_size = n;





			}






		}
		void insert(size_t pos, const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);

			}
			size_t end = _size + len;
			while (end > pos + len - 1)
			{
				_str[end] = _str[end - len];
				end--;

			}
			strncpy(_str + pos, str, len);
			_size += len;


		}
		size_t find(char ch, size_t pos = 0)
		{

			for (int i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
					return i;



			}
			return npos;





		}
		size_t find(const char* sub, size_t pos = 0) const
		{
			assert(pos < _size);
			const char* ptr = strstr(_str + pos, sub);
			if (ptr != nullptr)
			{
				return ptr - _str;

			}
			else
			{
				return npos;
			}





		}
		string substr(size_t pos = 0, size_t len = npos) const
		{
			string substr;

			if (pos > _size - len)
			{
				for (int i = pos; i <= _size; i++)
				{
					substr += _str[i];
				}


			}
			else
			{

				for (int i = pos; i < pos + len; i++)
				{
					substr += _str[i];
				}
				substr += '\0';

			}
			return substr;





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





		}
		string(const string& s)
		{
			string tmp(s._str);
			swap(tmp);
		
		
		
		
		}
		string& operator=(string tmp)
		{
			swap(tmp);
			return *this;
		}
		string& operator=(const string& s)
		{
			char* tmp = new char[s._capacity + 1];
			strcpy(tmp, s._str);
			delete[] _str;
			_str = tmp;
			_size = s._size;
			_capacity = s._capacity;
			return *this;

			




			

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

		}
		friend istream& operator>>(istream& in, string& s);
	public:
		static const int  npos;




	private:
		char* _str;
		int _size;
		int _capacity;



	};
	const int string::npos = -1;
	void swap(string& x, string& y)
	{
		x.swap(y);
		cout << "没使用库里的" << endl;
	
	}
	istream& operator>>(istream& in, string& s)
	{
		s.clear();

		char ch;

		ch = in.get();
		
		char buff[128];
		int i = 0;
		while (ch != ' ' && ch != '\n')
		{

			buff[i++] = ch;
			if (i == 127)
			{
				buff[127] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();


		}
		if (i > 0)
		{
			buff[i] = '\0';
			s += buff;
		}

		return in;




	}
	//istream& operator>>(istream& in, string& s)
	//{
	//	
	//	char ch;

	//	
	//	in.get(ch);
	//	
	//	s.reserve(128);

	//	while (ch != ' ' && ch != '\n')
	//	{

	//	
	//	
	//		s += ch;
	//		in.get(ch);


	//	}
	//	
	//		
	//		
	//	

	//	return in;




	//}
	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());



	}
	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)
	{
		for (auto e : s)
		{
			out << e;
		}
		return out;






	}
	//istream& operator>>(istream& in, string& s)
	//{
	//	s.clear();
	//	char ch;
	//	
	//	ch = in.get();
	//	//in >> ch;
	//	s.reserve(128);
	//	while (ch != ' ' && ch != '\n')
	//	{
	//		
	//		s += ch;
	//		ch = in.get();
	//		//in >> ch;

	//	}
	//	return in;
	//
	//
	//
	//
	//}
	void test1()
	{
		string str;
		str += 'a';

		str += 'b';
		str += "beijing";


		string::iterator it = str.begin();
		while (it != str.end())
		{
			cout << *it << " ";
			it++;

		}





	}
	void test2()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.push_back('a');
		str.push_back('a');
		string::iterator it = str.begin();
		while (it != str.end())
		{
			cout << *it << " ";
			it++;

		}
		cout << str[2];





	}
	void test3()
	{
		string str;
		str.append("stringbj");
		for (auto& e : str)
		{
			cout << e << " ";
		}


	}
	void print_string(const string it)
	{
		string::const_iterator res = it.begin();
		while (res != it.end())
		{
			cout << *res << " ";
			++res;



		}




	}
	void test4()
	{
		string str;
		str += "abc";
		str.append("stringbj");
		string::iterator it = str.begin();
		while (it != str.end())
		{
			cout << *it << " ";
			it++;

		}
		//str.insert(0, 'g');
		for (auto& e : str)
		{
			cout << e << " ";
		}
		cout << endl;
		// str.earse(1,string::npos);*/
		/* for (auto e : str)
		 {
			 cout << e << " ";
		 }*/
		 // print_string(str);



	}
	void test5()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.resize(10);
		/* string::iterator it = str.begin();
		 while (it != str.end())
		 {
			 cout << *it << " ";
			 it++;

		 }*/
		cout << str.c_str();







	}
	void test6()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.insert(2, "hello");
		cout << str.c_str();




	}
	void test7()
	{
		string str;
		str.push_back('a');
		str.push_back('a');
		str.push_back('b');
		str.insert(2, "hello");
		cout << endl;
		int ret = str.find('b', 0);
		cout << ret;


	}
	void test8()
	{
		string str;
		str += "beijing huanyingni zhangjiawang";
		int ret = str.find("zhangjiawang");
		cout << ret;




	}
	void test9()
	{
		string str;
		str += "beijing huanyingni zhangjiawang";
		string op = str.substr(0, 10);
		cout << op.c_str();




	}
	void test10()
	{
		string str1;
		string str2;
		str1 += "abc";
		str2 += "aba";

		cout << (str1 == str2) << endl;
		cout << ("aba" == str2) << endl;
		cout << (str2== "aba") << endl;
		 cout << (str1>str2) << endl;
		 cout << (str1 >=str2) << endl;
		 cout << (str1<str2) << endl;
		 cout << (str1 <=str2) << endl;
		 cout << (str1!=str2) << endl;




	}
	void test11()
	{
		string str1;
		string str2;
		cin >> str1;//>>str2;//>>str2;
		//cout << str1;
		cout << str1.capacity();




	}
	void test12()
	{   string str1;
		string str2;
		str1 += "hello";
		str2+="nihao";
		cout << "str1:"<<str1 << endl;
		cout << "str2:"<<str2 << endl;
		str1.swap(str2);
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;

	}
	void test13()
	{
		string str1;
		string str2;
		str1 += "hello";
		str2 += "nihao";
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;
		swap(str1, str2);
		cout << "str1:" << str1 << endl;
		cout << "str2:" << str2 << endl;
	
	
	}
	void test14()
	{
		
		string str2;
		
		str2 += "nihao";
		string str1(str2);
	
	
	
	}
	
}
	

.cpp

#include"标头.h"

int main()
{
  zjw::test11();
}

相关推荐

  1. MFC中CString的用法及使用示例

    2024-03-10 18:10:06       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-10 18:10:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-10 18:10:06       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-10 18:10:06       82 阅读
  4. Python语言-面向对象

    2024-03-10 18:10:06       91 阅读

热门阅读

  1. VUE2升级#总结1

    2024-03-10 18:10:06       45 阅读
  2. Pytho爬取音乐

    2024-03-10 18:10:06       38 阅读
  3. 计算机等级考试:信息安全技术 知识的四

    2024-03-10 18:10:06       44 阅读
  4. 非插件方式为wordpress添加一个额外的编辑器

    2024-03-10 18:10:06       37 阅读
  5. 算法练习第十二天|二叉树的递归遍历和迭代遍历

    2024-03-10 18:10:06       42 阅读
  6. 大数据架构

    2024-03-10 18:10:06       38 阅读
  7. typedef 别名的定义和使用

    2024-03-10 18:10:06       48 阅读
  8. springboot 下载 Excel 文件的 Controller 层案例

    2024-03-10 18:10:06       44 阅读
  9. AI辅助研发,引领科技新潮流

    2024-03-10 18:10:06       45 阅读