1. 程式人生 > >c++ — 實現一個簡單的string類

c++ — 實現一個簡單的string類

                      string類的實現

C++使用起來非常方便,原因的它裡面包含的類,這種面向物件的思想讓我們程式設計變得異常方便。今天我們來實現一個string類,這

個類主要的作用就是在C++中靈活的使用字串。現在我們一步一步的來,一個類首先應該寫出他的成員,和它的預設函式,構造函

數和解構函式顯得尤為重要,首先我們來看建構函式。

        //建構函式
	String(char *str ="")
		:_str(new char[strlen(str)+1])
	{
		strcpy(_str, str);
		cout << "String(const char *str)" << endl;
	}
	//拷貝建構函式
	String(const String& s)
		:_str(new char[strlen(s._str)+1])
	{
		cout << "String(const String& s)" << endl;
		strcpy(_str,s._str);
	}

這個時候我們分析程式碼為什麼。



裡我們用的是深拷貝的知識進行建構函式和拷貝建構函式。

深淺拷貝的問題可以看我的這個部落格:

http://blog.csdn.net/dawn_sf/article/details/61633384

裡面有深淺拷貝的問題。

現在我們用第二種方法 用寫時拷貝的知識進行string類的構造 

具體的可以看我這個部落格: 

http://blog.csdn.net/dawn_sf/article/details/66522352

裡面有寫時拷貝詳細的講解

接下來使我們的解構函式

~String()
	{
		cout << "!String()" << endl; 
		if (_str != NULL)
		{
			delete[] _str;
		}
	}

這個函式挺簡單的就不說了。

現在看看拷貝構造和構造執行的結果:

int main()
{
	String str1("abcdefg");
	cout << str1 << endl;
	String str2(str1);
	cout << str2 << endl;
	return 0;
}


這裡沒問題吧,一次構造 一次拷貝構造,2次析構,並且打印出來內容也相等。

現在還有一個運算子過載了。我們只需要過載一個“=”號就可以,其他方法相似。

String& operator=(const String& s)
{
cout << "Stndl;ring& operator=(const String& s)" << endl;
if (&s != this)
{
delete[] _str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
strcpy(_str, s._str);
}
return *this;
}

除過這種方法還有一種很牛逼的方法,但是不容易思考。

下面來看看這個方法:

String& operator=(String& s)
	{
		cout << "Stndl;ring& operator=(const String& s)" << endl;
		std::swap(_str, s._str);
		return *this;
	}
這個swap方法是系統提供的,就是交換內容,不需要考慮實現。



一個基本的String類已經被我構造起來了,最後我們看一看程式能不能跑過去:

# define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<Windows.h>
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);
		cout << "String(const char *str)" << endl;
	}
	//拷貝建構函式
	String(const String& s)
		:_str(new char[strlen(s._str)+1])
	{
		cout << "String(const String& s)" << endl;
		strcpy(_str,s._str);
	}
	String& operator=(String& s)
	{
		cout << "Stndl;ring& operator=(const String& s)" << endl;
		std::swap(_str, s._str);
		return *this;
	}
	~String()
	{
		cout << "~String()" << endl; 
		if (_str != NULL)
		{
			delete[] _str;
		}
	}
private:
    char *_str;
};

ostream& operator<<(ostream& os, const String& s)
{
	os << s._str;
	return os;
}
int main()
{
	String str1("abcdefg");
	cout << str1 << endl;;
	String str2(str1);
	String str3;
	str3 = str2;
	cout << str3 << endl;
	return 0;
}



可以看出來沒有任何問題,先構造str1,然後列印,在拷貝構造str2,再構造str3,然後呼叫運算子重

載給str3賦值,然後列印str3,最後從str3到str1依次析構,好完美~~。