C++深浅拷贝——实现String类

本文通过具体的C++代码示例详细解释了浅拷贝与深拷贝的概念及其实现方式,包括如何避免浅拷贝导致的问题,并介绍了引用计数的方法来优化内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块内存,当一个对象将这块内存释放掉之后,另一些对象不知道该块空间已经还给了系统,以为还有效,所以在对这段内存进行操作的时候,发生了访问违规。

当类里面有指针对象时,拷贝构造和赋值运算符重载只进行值拷贝(浅拷贝),两个对象向同一块内存,对象销毁时该空间被释放了两次,因此程序崩溃!

深拷贝:为不同的指针对象各自开辟空间。


浅拷贝实现String类:(错误版)

class String
{
public:
	String(const char *str = NULL);
	String(const String &other);
	String& operator = (const String &other);
	~String();
private:
	char *m_data;
};

String::String(const char *str)
{
	if(str == NULL)
	{
		m_data = new char[1];
		*m_data = '\0';
	}
	else
	{
		int length = strlen(str);
		m_data = new char[length+1];
		strcpy(m_data, str);
	}
}

String::String(const String &other)
{
	strcpy(m_data, other.m_data);
}

String & String::operator =(const String &other)
{  
	//检查自赋值
	if(this == &other)
	{
		return *this;  
	}
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);

	//返回当前对象的引用
	return *this;
}

String::~String()
{
	delete[] m_data;
	m_data = NULL;
}




int main()
{
	String s;
	String s1 = "1111";
	String s4 = "33333";
	String s5 = "444444";
	String s6 = "666";
	String s2(s1);
	String s3 = "22222";
	String s7;
	String s8("hello world!");

	s1 = s3;


	system("pause");
	return 0;
}

拷贝构造函数:


赋值运算符的重载:

运行结果:




深拷贝:(普通版)

class String
{
public:
	String(const char *str = NULL);
	String(const String &other);
	String& operator = (const String &other);
	~String();
private:
	char *m_data;
};

String::String(const char *str)
{
	if(str == NULL)
	{
		m_data = new char[1];
		*m_data = '\0';
	}
	else
	{
		int length = strlen(str);
		m_data = new char[length+1];
		strcpy(m_data, str);
	}
}

String::String(const String &other)
{
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);
}

String & String::operator =(const String &other)
{  
	检查自赋值
	if(this == &other)
	{
		return *this;  
	}

	释放原有的内存资源
	delete[] m_data;

	分配新的内存资源,并复制内容
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);

	返回当前对象的引用
	return *this;
}

String::~String()
{
	delete[] m_data;
	m_data = NULL;
}




int main()
{
	String s;
	String s1 = "1111";
	String s4 = "33333";
	String s5 = "444444";
	String s6 = "666";
	String s2(s1);
	String s3 = "22222";
	String s7;
	String s8("hello world!");

	s1 = s3;


	system("pause");
	return 0;
}
浅拷贝:(引用计数版)

//浅拷贝:引用计数版
class String
{
public:
	String(char *pStr = "")
		:_pCount(new int(1))
	{
		if(NULL == *pStr)
		{
			pStr = new char[1];
			*pStr = '\0';
		}
		else
		{
			_pStr = new char[strlen(pStr)+1];
			strcpy(_pStr,pStr);
		}
	}
	String(const String& s)
		:_pStr(s._pStr)
		,_pCount(s._pCount)
	{
		++(*_pCount);
	}
	String& operator = (const String& s)
	{
		if(--(*_pCount) == 0 && _pStr)
		{
			delete[] _pStr;
			delete _pCount;
		}
		_pStr = s._pStr;
		_pCount = s._pCount;
		++(*_pCount);

		return *this;
	}
	~String()
	{
		if(--(*_pCount) == 0)
		{
			delete[] _pStr;
			delete _pCount;
			_pStr = NULL;
			_pCount = NULL;
		}
	}

private:
	char* _pStr;
	int* _pCount;
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值