C++ 中string類的三種模擬實現方式

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

測試結果:

650) this.width=650;" src="http://s5.51cto.com/wyfs02/M02/7E/5D/wKiom1b9HMiDvU4LAABm5xdVbMc832.png" title="9NS]J@WUEJK%{OZF8AJHC8M.png" alt="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;
}

測試結果:

650) this.width=650;" src="http://s1.51cto.com/wyfs02/M02/7E/5E/wKiom1b9IHLyb9YkAACCs5115q8614.png" title="$]{CP_1YV63GOGM@TE[X8DP.png" alt="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;
}

測試結果:

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/7E/5E/wKiom1b9IvPDXxIsAACQRqXzAYw983.png" title="4)9IMQEIQ(]$VB%URZI[MA4.png" width="600" height="339" border="0" hspace="0" vspace="0" style="width:600px;height:339px;" alt="wKiom1b9IvPDXxIsAACQRqXzAYw983.png" />

這就是三種模擬string類的實現方式。

本文出自 “Pzd流川楓” 博客,請務必保留此出處http://xujiafan.blog.51cto.com/10778767/1758991

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章