实现CMyString类--深拷贝与浅拷贝

时间:2021-04-06 19:51:41

实现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:
实现CMyString类--深拷贝与浅拷贝
实现CMyString类--深拷贝与浅拷贝
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:
实现CMyString类--深拷贝与浅拷贝
图2:

实现CMyString类--深拷贝与浅拷贝
实现CMyString类--深拷贝与浅拷贝

实现CMyString类--深拷贝与浅拷贝