深拷贝和浅拷贝

对象拷贝(Object Copy)就是将一个对象的属性拷贝到另一个有着相同类类型的对象中去。在程序中拷贝对象是很常见的,主要是为了在新的上下文环境中复用对象的部分或全部 数据。有两种类型的对象拷贝:浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。

浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针

浅拷贝用例:系统默认的拷贝构造函数和赋值运算符重载函数都是浅拷贝

class CGoods
{
public:
	CGoods()
	{
		cout << this << " :CGoods::CGoods()" << endl;
	}
	CGoods(char* name, float price, int amount)
	{
		cout << this << " :CGoods::CGoods(char*,float,int)" << endl;
		mname = new char[strlen(name) + 1]();
		strcpy(mname, name);
		mprice = price;
		mamount = amount;
	}
	~CGoods()
	{
		cout << this << " :~CGoods()" << endl;
		delete[] mname;
		mname = NULL;
	}
private:
	char* mname;
	float mprice;
	int mamount;
};
void main()
{
	CGoods good1("good1", 20.1f, 10);
	CGoods good2=good1;
}

结果分析:

执行结果:调用一次构造函数,调用两次析构函数,两个对象的指针成员所指内存相同,这会导致什么问题呢?

mname指针被分配一次内存,但是程序结束时该内存却被释放了两次,会造成内存泄漏问题!

这是由于编译系统在我们没有自己定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行的是浅拷贝!即对指针name拷贝后会出现两个指针指向同一个内存空间。

所以,在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生。

深拷贝的实现:

class CGoods
{
public:
	CGoods()
	{
		cout << this << " :CGoods::CGoods()" << endl;
	}
    CGoods(char* name, float price, int amount)
	{
		cout << this << " :CGoods::CGoods(char*,float,int)" << endl;
		mname = new char[strlen(name) + 1]();
		strcpy(mname, name);
		mprice = price;
		mamount = amount;
	}
	
	//深拷贝
	CGoods(const CGoods& rhs)
	{
		cout << this << " :CGoods::CGoods(CGoods)" << endl;
		mname = new char[strlen(rhs.mname) + 1]();
		strcpy(mname, rhs.mname);
		mprice = rhs.mprice;
		mamount = rhs.mamount;
	}
	
	
	//深拷贝
	CGoods& operator=(const CGoods& rhs)
	{
		cout << this << " :CGoods::operator=(CGoods)" << endl;
		if (this != &rhs)
		{
			delete[] mname;
			mname = new char[strlen(rhs.mname) + 1];
			strcpy(mname, rhs.mname);
			mprice = rhs.mprice;
			mamount = rhs.mamount;
		}
		return *this;
	}
	
	~CGoods()
	{
		cout << this << " :~CGoods()" << endl;
		delete[] mname;
		mname = NULL;
	}
private:
	char* mname;
	float mprice;
	int mamount;
};
void main()
{
	CGoods good1("good1", 20.1f, 10);
	CGoods good2=good1;
}

执行结果:

结果分析:

当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形:

1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现;

2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值