1.原始版本(拷贝构造和赋值运算符重载时,需要重新开辟空间)


#include <iostream>
#include <string>

using namespace std;

class String
{
	friend ostream& operator<<(ostream& os, const String& S);
public:
	String(char* str = "")
		:_str(new char[strlen(str)+1])
	{
		strcpy(_str, str);
	}
	String(const String& S)
		:_str(new char[strlen(S._str)+1])
	{
		strcpy(_str, S._str);
	}
	String& operator=(const String& S)
	{
		if(_str != S._str)
		{
			delete[] _str;
			_str = new char[strlen(S._str)+1];
			strcpy(_str, S._str);
		}
		return *this;
	}
	~String()
	{
		if(_str != NULL)
		{
			delete[] _str;
		}
	}

private:
	char* _str;
};

ostream& operator<<(ostream& os, const String& S)
{
	os<<S._str;
	return os;
}

int main()
{
	String s1("abcde");
	cout<<s1<<endl;
	String s2(s1);
	cout<<s2<<endl;
	String s3;
	cout<<s3<<endl;
	s3 = s2;
	cout<<s3<<endl;
	system("pause");
	return 0;
}

测试结果:

wKiom1b9HMiDvU4LAABm5xdVbMc832.png


2.引用计数方式(拷贝构造时和赋值运算符重载时,只需对其引用计数器操作)


#include <iostream>
#include <string>
using namespace std;

class String
{
	friend ostream& operator<<(ostream& os, const String& S);
public:
	String(char* str = "")
		:_str(new char[strlen(str)+1]),_pcount(new int(1))
	{
		strcpy(_str, str);
	}
	String(const String& S)
		:_str(new char[strlen(S._str)+1])
		,_pcount(S._pcount)
	{
		strcpy(_str, S._str);
		++(*_pcount);
	}
	String& operator=(const String& S)
	{
		if(_str != S._str)
		{
			delete[] _str;
			delete _pcount;
			_str = new char[strlen(S._str)+1];
			_pcount = S._pcount;
			strcpy(_str, S._str);
			++(*_pcount);
		}
		return *this;
	}
	~String()
	{
		if(--(*_pcount) == 0)
		{
			delete[] _str;
			delete _pcount;
		}
	}
private:
	char* _str;
	int* _pcount;
};

ostream& operator<<(ostream& os, const String& S)
{
	os<<S._str;
	return os;
}

int main()
{
	String s1("abcde");
	cout<<s1<<endl;
	String s2(s1);
	cout<<s2<<endl;
	String s3;
	cout<<s3<<endl;
	s3 = s2;
	cout<<s3<<endl;

	system("pause");
	return 0;
}

测试结果:

wKiom1b9IHLyb9YkAACCs5115q8614.png

3.现代写法(拷贝构造和赋值运算符重载时,只进行指针的交换,没有开辟额外的空间,采用值传方式进行拷贝构造和赋值,最后节约了空间,只不过相对于前两种多调用了一次拷贝构函数,以时间换取空间)


#include <iostream>
#include <string>

using namespace std;
class String
{
	friend ostream& operator<<(ostream& os, const String& S);
public:
	String(char *str = "")			//构造函数
		:_str(new char[strlen(str)+1])
	{
		strcpy(_str, str);
	}
	String(const String& str)	//拷贝构造函数
		:_str(NULL)
	{
		String tmp(str._str);
		swap(_str, tmp._str);
	}

	String& operator=(String str)	//赋值运算符重载
	{
		swap(_str, str._str);
		return *this;
	}
	~String()				 //析构函数
	{
		if(_str != NULL)
		{
			delete[] _str;
		}
	}
private:
	char* _str;
};

ostream& operator<<(ostream& os, const String& S)
{
	os<<S._str;
	return os;
}
int main()
{
	String s1("abcde");
	cout<<s1<<endl;
	String s2(s1);
	cout<<s2<<endl;
	String s3;
	cout<<s3<<endl;
	s3 = s2;
	cout<<s3<<endl;
	system("pause");
	return 0;
}

测试结果:

wKiom1b9IvPDXxIsAACQRqXzAYw983.png

这就是三种模拟string类的实现方式。