深度复制和浅复制的区别是什么?
当前回答
浅拷贝构造一个新的复合对象,并将其对原始对象的引用插入其中。
与浅拷贝不同,deepcopy构造新的复合对象,并插入原复合对象的原对象副本。
让我们举个例子。
import copy
x =[1,[2]]
y=copy.copy(x)
z= copy.deepcopy(x)
print(y is z)
上面的代码输出FALSE。
让我们看看怎么做。
原始复合对象x=[1,[2]](称为复合,因为它在对象中有对象(Inception))
如图所示,列表中有一个列表。
然后使用y = copy.copy(x)创建它的浅拷贝。python在这里所做的是,它将创建一个新的复合对象,但其中的对象指向原始对象。
在图像中,它为外层列表创建了一个新的副本。但内部列表与原始列表保持一致。
现在我们使用z = copy.deepcopy(x)创建它的深度复制。python在这里所做的是,它将为外部列表和内部列表创建新对象。如下图所示(红色高亮部分)。
最后代码输出False,因为y和z不是相同的对象。
HTH.
其他回答
广度vs深度;从引用树的角度考虑,将对象作为根节点。
浅:
变量A和B指的是不同的内存区域,当B被分配给A时,这两个变量指的是相同的内存区域。后来对其中一个内容的修改立即反映在另一个的内容中,因为它们共享内容。
深:
变量A和B指的是不同的内存区域,当B被分配给A时,A所指向的内存区域中的值被复制到B所指向的内存区域。后来对其中一项内容的修改仍为A或B所独有;内容不共享。
复制array:
Array是一个类,这意味着它是引用类型,因此array1 = array2的结果 在引用同一个数组的两个变量中。
但是看看这个例子:
static void Main()
{
int[] arr1 = new int[] { 1, 2, 3, 4, 5 };
int[] arr2 = new int[] { 6, 7, 8, 9, 0 };
Console.WriteLine(arr1[2] + " " + arr2[2]);
arr2 = arr1;
Console.WriteLine(arr1[2] + " " + arr2[2]);
arr2 = (int[])arr1.Clone();
arr1[2] = 12;
Console.WriteLine(arr1[2] + " " + arr2[2]);
}
浅克隆意味着只复制克隆数组所表示的内存。
如果数组包含值类型对象,则复制值;
如果数组包含引用类型,则只复制引用-因此有两个数组,其成员引用相同的对象。
要创建复制引用类型的深度复制,必须循环遍历数组并手动克隆每个元素。
试着考虑下面的图像
例如Object。memberwisclone创建一个浅复制链接
并使用ICloneable接口,你可以得到深度拷贝,如这里所述
摘自[博客]:http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
深度复制涉及使用一个对象的内容创建同一类的另一个实例。在深度复制中,两个对象可能包含相同的信息,但目标对象将有自己的缓冲区和资源。任何一个对象的销毁都不会影响剩下的对象。重载赋值操作符将创建对象的深层副本。
浅拷贝包括将一个对象的内容复制到同类的另一个实例中,从而创建镜像。由于直接复制引用和指针,这两个对象将共享另一个对象的相同外部包含内容,这是不可预测的。
解释:
Using a copy constructor we simply copy the data values member by member. This method of copying is called shallow copy. If the object is a simple class, comprised of built in types and no pointers this would be acceptable. This function would use the values and the objects and its behavior would not be altered with a shallow copy, only the addresses of pointers that are members are copied and not the value the address is pointing to. The data values of the object would then be inadvertently altered by the function. When the function goes out of scope, the copy of the object with all its data is popped off the stack.
如果对象有任何指针,则需要执行深度复制。对于对象的深层拷贝,在自由存储区中为对象分配内存,并复制指向的元素。深度拷贝用于函数返回的对象。
为了补充其他答案,
对象的浅拷贝对值类型执行逐值复制 基于属性,并通过引用复制基于引用类型的属性。 对象的深度复制对基于值类型的对象执行逐值复制 属性,以及基于引用类型的按值复制 层次结构深处的属性(引用类型)
推荐文章
- 在支持循环和函数的语言中,是否存在“goto”的合法用例?
- 为什么不使用异常作为常规的控制流呢?
- 什么是序列化?
- 如何从表中导出所有数据到可插入的sql格式?
- 我如何复制一个哈希在Ruby?
- 每个递归都可以转换成迭代吗?
- 什么是ORM,它是如何工作的,我应该如何使用它?
- 我能在服务器端应用程序(PHP、Ruby、Python等)上读取URL的哈希部分吗?
- 多少个参数是太多?
- Git复制文件保存历史
- 对于不可变集合上的非突变“add”方法,最好的名称是什么?
- foo到底是什么意思?
- MySQL:在同一个MySQL实例上克隆MySQL数据库
- foreach和map有区别吗?
- 设计模式:工厂vs工厂方法vs抽象工厂