【C++】基础语法:深浅拷贝

前言

在学习拷贝构造函数的时候遇到了深浅拷贝这个知识点 就写篇文章记录一下

(引用的部分不用太在意 是查的
(需要前提知识:知道默认拷贝构造函数是什么 知道默认拷贝构造函数和构造函数的关系、知道析构函数的写法和用处

浅拷贝

浅拷贝(Shallow Copy)是指创建一个新的对象,并将原始对象的非静态字段复制到新对象。如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的,则复制引用但不复制引用的对象。这意味着原始对象和复制对象引用同一个对象,所以任何对复制对象的修改都可能影响到原始对象。因此,浅拷贝操作后的两个对象共享同一个底层数据源。

简单来说就是 逐个字节拷贝
被拷贝以及拷贝对象它们的值是完全相同的

深拷贝

深拷贝(Deep Copy)则是指创建一个完全独立的新对象,并递归地复制原始对象及其所有子对象。这意味着无论对象的层级有多深,新对象和原对象都是完全独立的。修改其中一个对象不会影响另一个对象。深拷贝会复制对象的所有层级,包括对象的属性、嵌套对象、引用等。

一般来说 涉及到动态开辟的对象在拷贝的时候 都需要深拷贝

对比

我们借助一段代码来比较深浅拷贝的区别 以及为什么要存在深拷贝

为没学栈的同学解释一下:下面这段代码就是创建了两个对象s1 和s2 然后将1、2、3、4逐个存入s1中 调用了默认拷贝构造函数将s1拷贝给s2 并且用的是浅拷贝的方式

typedef int DataType;
class Stack
{
public:
	Stack(size_t capacity = 10)
	{
		_array = (DataType*)malloc(capacity * sizeof(DataType));
		if (nullptr == _array)
		{
			perror("malloc申请空间失败");
			return;
		}
		_size = 0;
		_capacity = capacity;
	}
	void Push(const DataType& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		if (_array)
		{
			free(_array);
			_array = nullptr;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};
int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	Stack s2(s1);
	return 0;
}

下面是s1和s2中array数组首元素指针的存储情况
在这里插入图片描述
根据浅拷贝逐字节拷贝的特点我们可以看出来 这两个array的地址是相同的 他们指向的是同一块空间
这就会导致在析构的时候 先释放了st2 再释放st1的时候就访问了野指针 程序直接崩溃

下面这段代码是深拷贝的写法

// Stack st2(st1);
//s就是st1 this是st2
Stack(const Stack& s)
{
	DataType* tmp = (DataType*)malloc(s._capacity *(sizeof(DataType)));
	if (tmp == nullptr)
	{
		perror("malloc fail");
		exit(-1);
	}
	//上面几行看不懂的话不用管
	memcpy(tmp, s._array, sizeof(DataType) * s._size);

	_array = tmp;
	_size = s._size;
	_capacity = s._capacity;
}

在这里插入图片描述

而深拷贝则会根据array的大小 来开辟一块和array大小一样的空间 那么在析构的时候就没问题了

结论

所以在函数传参的时候 建议用引用 其次可以用指针 最不建议用传值
并且引用应该也是最方便的

结语

对于深浅拷贝的简单介绍到这里就结束了 后面会更深入的介绍 希望对你有帮助~~

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值