浅拷贝与深拷贝
写在前面
原文出处,原文大佬讲的很细致明了,此文相当于读书笔记
0x00 数据
拷贝的概念用于引用数据类型(真实的数据存放在堆内存当中),浅拷贝类似于变量的赋值,只是将内部的值 copy 一份,但并不要将浅拷贝的理解止步于此,不然会出问题的!
程序中的数据可以分为两类:
- 基本数据类型:也即常见的 int, double, string...... 之类的编程语言明确声明的基本数据类型
- 引用数据类型:除基本类型外的所有数据都是引用数据类型,我们为其声明的变量名里存的指针指向的只是他在栈中的内存地址,而真正的数据实体存在于堆内存当中,当我们通过变量名来使用引用对象时,编译器首先检索的是栈中的地址,然后再去堆中取出相应的数据实体。
0x01 深拷贝和浅拷贝
1、浅拷贝
上文说到过,浅拷贝类似于赋值。赋值的概念是对于基本数据类型来说的,他们的值都存在栈中,将一个基本数据类型变量值赋给另外一个基本数据类型变量时,编译器会完全复制他所指向栈地址当中所保存的数据,而基本数据类型指向的栈中保存的就是数据实体。所以在引用类型中的基本数据类型上,浅拷贝和赋值其实是一样的。
但是!引用类型当中也可以存在其他的引用类型,对于这些数据跟上面就有区别了。
引用类型的浅拷贝依然是复制其在栈中的值,但是引用类型指向的栈内存中存的并不是数据实体,而是该实体在堆内存中的地址,这样的拷贝就会让两个对象指向同一块堆内存当中的数据实体。那么其中一个对象对实体进行更改,势必会影响到其他同样指向该实体的对象。这也正是浅拷贝与复制的区别所在。
2、深拷贝
深拷贝较于浅拷贝就比较好理解了,他会直接把所有的数据直接新建一份一样的,这份数据在栈和堆中都是不一样的地址(尽管他们的数据都是相同的),那么这样的拷贝方式显然不会影响到原数据。