實現CMyString類--深拷貝與淺拷貝

實現CMyString類,實現賦值運算符函數(深拷貝與淺拷貝(寫時拷貝))

深拷貝:賦值運算符函數說明
步驟1、釋放原來的內存空間
步驟2、再重新開闢要賦值的對象的大小的空間
步驟3、再將另一個對象的值拷貝給this對象

友元函數的說明:由於輸出重載需要倆個參數,不能再隱含this指針,故使用友元函數

代碼如下:

<span style="font-size:18px;">class CMyString
{
public:
	CMyString()
		:str(new char[1])
	{
		str[0] = '\0';
	}
	CMyString(char* _str)
		:str(new char[strlen(_str)+1])
	{
		strcpy(str, _str);
	}
	CMyString(CMyString& s)
		:str(NULL)
	{
		delete[] str;
		str = new char[strlen(s.str) + 1];
		strcpy(str, s.str);
	}
	CMyString& operator=(CMyString& s)
	{
		if (this != &s)
		{
			delete[] str;
			str = new char[strlen(s.str) + 1];
			strcpy(str, s.str);
		}
		return *this;
	}
	~CMyString()
	{
		if (str)
		{
			delete[] str;
			str = NULL;
		}
	}
	friend ostream& operator<<(ostream& os,CMyString& s)
	{
		os << s.str;
		return os;
	}
private:
	char* str;
};</span>


淺拷貝:賦值運算符函數說明
步驟1、Release();
步驟2、將this->str 指向 s.str;
步驟3、++GetCount(str);
GetCount()函數說明:得到當前對象的引用計數--->*(int*)(str-4);
減4是因爲對象在創建的時候除了多開闢了一個字節給‘|0’,還多給引用計數開闢了4個字節,且將str指向了引用計數的後4個字節(即字符串處),要得到引用計數需減4,如下圖1:


Release()函數說明:判斷str是否爲空且引用計數減1之後是否爲0;如果減1之後爲0,說明後期無對象再去使用這塊內存,則將其釋放掉,反之不去釋放;

寫時拷貝char& operator[](size_t index);函數說明:
步驟1、減去引用計數
步驟2、拷貝
步驟3、創建引用計數

代碼如下:

<span style="font-size:18px;">class CMyString
{
private:
	void Release()
	{
		if (str && --GetCount(str) == 0)
		{
			delete[](str - 4);
			str = NULL;
		}
	}
	int& GetCount(char* str)
	{
		return (*(int*)(str - 4));
	}
public:
	CMyString(char* _str = "")
		:str(new char[strlen(_str) + 5])
	{
		*(int*)str = 1;
		str += 4;
		strcpy(str, _str);
	}
	CMyString(const CMyString& s)
		:str(s.str)
	{
		++GetCount(str);
	}
	CMyString& operator=(const CMyString& s)
	{
		if (this != &s)
		{
			Release();
			str = s.str;
			++GetCount(str);
		}
		return *this;
	}
	//寫時拷貝
	char& operator[](size_t index)
	{
		if (GetCount(str) > 1)
		{
			--GetCount(str);
			char* tmp = new char[strlen(str) + 5];
			tmp += 4;
			GetCount(tmp) = 1;
			strcpy(tmp, str);
			str = tmp;
		}
		return str[index];
	}
	~CMyString()
	{
		Release();
	}
	friend ostream& operator<<(ostream& os, CMyString& s)
	{
		os << s.str;
		return os;
	}
private:
	char* str;
};</span>

測試用例代碼:

int main()
{
	CMyString s1("hello");
	CMyString s2;
	s2 = s1;
	CMyString s3 = s1;
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	//淺拷貝中的寫時拷貝測試用例
	s3[0] = 'b';
	s3[1] = 'l';
	s3[2] = 'k';
	cout << s3 << endl;
	return 0;
}

測試結果如下圖2:

圖1:

圖2:












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