对象的浅拷贝和深拷贝

对象的浅拷贝和深拷贝

#include <iostream>
using namespace std;

class SeqStack
{
public:
	SeqStack(int size = 10) :_size(size),_top(-1)
	{
		_pstack = new int[size];
	}
	~SeqStack()
	{
		delete[] _pstack;
		_pstack = nullptr;
	}
	bool isEmpty()
	{
		return _top == -1;
	}
	bool isFull()
	{
		return _top == _size - 1;
	}
	void push(int val)
	{
		if (isFull())
			resize();
		_pstack[++_top] = val;
	}
	void pop()
	{
		if (isEmpty())
			return;
		_top--;
	}
	int top()
	{
		return _pstack[_top];
	}
private:
	int* _pstack;
	int _top;
	int _size;

	void resize()
	{
		int* tmp = new int[_size * 2];
		for (int i = 0; i < _size; i++)
		{
			tmp[i] = _pstack[i];
		}
		delete[]_pstack;
		_pstack = tmp;
		_size *= 2;
	}
};

int main()
{
	SeqStack s1;
	SeqStack s2(s1);
	SeqStack s3 = s1;

	return 0;
}

运行上面的代码,程序会发出这样的错误。在这里插入图片描述
在调试定位错误的时候发现,它是在main函数执行结束调用SeqStack析构函数时引起的。

在定义一个类时,如果我们没有写自己的构造析构函数,系统会自动给我们生成默认的构造析构函数,其中就包括拷贝构造函数。
而系统默认的拷贝构造函数是内存拷贝,也就是浅拷贝,在执行这行指令 SeqStack s2(s1);时,调用SeqStack的拷贝构造函数,把s1成员的值直接拷贝一份给s2, SeqStack s3 = s1;同理。
这时就有了三个指针指向s1的成员_pstack所指向的内存。
在这里插入图片描述

在main执行完毕时,会依次调用s3、s2、s1的析构函数,而他们的_pstack指针都指向同一块内存,p3析构函数执行结束后,这块内存已经被释放了,s2和s1的_pstack就成了野指针,对野指针delete时,自然就会引发程序崩溃,这就是对象浅拷贝所带来的隐患。

对象浅拷贝并不一定会出现错误,但是在占用外部资源的情况下,那浅拷贝一定会出现问题。

在对象占用外部资源的情况下,比如成员中有指针,并且这个指针指向的是一块new出来的内存,这时候我们就需要深拷贝来实现自己的拷贝构造函数。

系统默认生成的拷贝构造函数是这样的:

SeqStack(const SeqStack& s)
{
	_pstack = s._pstack;
	_size = s._size;
	_top = s._top;
}

直接把指针的值赋给新对象。

深拷贝的自定义拷贝构造函数:

SeqStack(const SeqStack& s)
{
	_pstack = new int[s._size];
	for (int i = 0; i <= s._top; i++)
	{
		_pstack[i] = s._pstack[i];
	}
	_size = s._size;
	_top = s._top;
}

出除了拷贝构造会出现浅拷贝问题,赋值构造函数(operator=)也会出现,除了浅拷贝的隐患,还有就是内存泄露的问题,我们也需要重新定义赋值构造函数实现深拷贝。

SeqStack& operator=(const SeqStack& s)
{
	if (this == &s)
		return *this;
	delete[] _pstack;
	_pstack = new int[s._size];
	for (int i = 0; i <= s._top; i++)
	{
		_pstack[i] = s._pstack[i];
	}
	_size = s._size;
	_top = s._top;
	return *this;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值