拷贝构造

本文详细介绍了C++中深拷贝和浅拷贝的概念,通过示例展示了如何在自定义类中实现深拷贝构造函数和深拷贝赋值运算符。强调了深拷贝在防止数据共享和避免`doublefree`异常中的重要性,并提供了String和Integer类的深拷贝实现。同时,讨论了拷贝赋值操作的注意事项,包括防止自赋值和内存管理策略。
摘要由CSDN通过智能技术生成

浅拷贝和深拷贝

浅拷贝:如果一个类包含指针形式的成员变量,缺省的拷贝构造函数只是复制指针变量本身,而没有复制该指针所指向的内容,这种拷贝方式称为浅拷贝。

深拷贝:浅拷贝将导致不同对象间的数据共享,在delete时会引发"double free"异常。因此必须自己定义一个支持复制指针所指向内容的拷贝构造函数,即深拷贝。

#include <iostream>
using namespace std;

class Integer{
public:
	Integer(int data):m_data(new int(data)){}
	~Integer(void)
	{
		delete m_data;
		m_data - NULL;
	}

	//缺省拷贝构造函数:浅拷贝
	//Integer(const Integer& that):m_data(that.m_data){}

	//自定义深拷贝构造函数
	Integer(const Integer& that):m_data(new int(*that.m_data))
	{
		//m_data = new int(*that.m_data);
		//*m_data = *that.m_data;
	}

	int get(void) const
	{
		return *m_data;
	}

private:
	int* m_data;
};

//测试用例
int main(void)
{
	Integer i(100);
	cout << i.get() << endl;  //100
	Integer i2(i);
	cout << i2.get() << endl;
	return 0;
}

实现String类

#include <iostream>
#include <cstring>

using namespace std;

class String{
public:
	String(const char* str = ""):m_str(strcpy(new char[strlen(str) + 1],str)){}
	~String(void)
	{
		delete[] m_str;
		m_str = NULL;	
	}

	//自定义深拷贝构造
	String(const String& that):
	        m_str{strcpy(new char[strlen(that.m_str) + 1],that,m_str)}
	        
	//自定义深拷贝赋值函数
	String& operator=(const String& that)
	{
		if(&tha != this)
		{
			char* str = new char[strlen(that.m_str) + 1];
			delete[] m_str;
			m_str = strcpy(str,that.m_str);
		}

		return *this;
	}

	const char* c_str(void) const
	{
		return m_str;
	}

private:
	char* m_str;
};

拷贝赋值

类的缺省拷贝赋值和缺省拷贝构造一样,是浅拷贝。为了得到深拷贝的效果,必须自定义拷贝赋值运算符函数。
拷贝赋值函数伪代码格式:

类名& operator=(const ()类型& that)
{
	if(this != &that)  //防止自赋值
	{
		//1,分配新内存
		//2,释放就内存
		//3,拷贝数据到新内存
	}

	return *this;  //4,返回自引用
}

一、字符串类型的深拷贝和浅拷贝赋值。
实现String类的深拷贝赋值函数

#include <iostream>
#include <cstring>

using namespace std;

class String{
public:
	String(const char* str = ""):m_str(strcpy(new char[strlen(str) + 1],str)){}
	~String(void)
	{
		delete[] m_str;
		m_str = NULL;
	}

	//深拷贝
	String(const String& that):m_str(strcpy(new char[strlen(that.m_str) + 1],that.m_str)){}

	//编译器会为类提供一个浅拷贝赋值函数
	//i2 = i3 -> i2.operator=(i3), 浅拷贝
	/*String& operator=(const String& that)
	{
		m_str = that.m_str;
		return *this;  //返回自引用
	}*/

	//自定义深拷贝赋值
	String& operator=(const String& that)
	{
		if(this != &that)
		{
			/* 基础版
				m_str = new char[strlen(that.m_str) + 1];
				strcpy(m_str,that.m_str);
			*/

			/*版本二,此版本先删除有风险,考虑new失败情况
			  delete[] m_str;
			  m_str = new char[strlen(that.m_str) + 1];
			  strcpy(m_str,that.m_str);
			*/
			//版本三
			char* str = new char[strlen(that.m_str) + 1];
			delete[] m_str;
			m_str = strcpy(str,that.m_str);

			/*版本四
			String temp(that);
			swap(m_str,temp.m_str);
			*/
		}

		return *this;
	}

	const char* c_str(void) const
	{
		return m_str;
	}

private:
	char* m_str;
};

二、整型类型的深拷贝和深拷贝赋值

#include <iostream>
using namespace std;
class Integer{
public:
	Integer(int data = 0):m_data(new int(data)){}
	~Integer(void)
	{
		delete m_data;
		m_data  = NULL;
	}
	
	//拷贝构造函数
	Integer(const Integer& that)
	                     :m_data(new int(*that.m_data)){}
	 
	 //深拷贝赋值函数
	 Integer& operator=(const Integer& that)
	{
		if(&that != this)
		{
			int* p_data = new int(*that.m_data);
			delete m_data;
			m_data = p_data;
		}
		return *this;
	}     

	const int get(void) const
	{
		return *m_data;
	}               

private:
	int* m_data;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值