深度复制和浅复制的区别是什么?
当前回答
除了上述所有定义之外,还有一个最常用的深度复制,位于类的复制构造函数(或重载赋值操作符)中。
浅复制——>是当你没有提供复制构造函数时。在这里,只复制对象,但不复制类的所有成员。
深度复制——>是当您决定在类中实现复制构造函数或重载赋值,并允许复制类的所有成员时。
MyClass& MyClass(const MyClass& obj) // copy constructor for MyClass
{
// write your code, to copy all the members and return the new object
}
MyClass& operator=(const MyClass& obj) // overloading assignment operator,
{
// write your code, to copy all the members and return the new object
}
其他回答
浅拷贝不会创建新的引用,但深拷贝会创建新的引用。
下面是程序解释的深拷贝和浅拷贝。
public class DeepAndShollowCopy {
int id;
String name;
List<String> testlist = new ArrayList<>();
/*
// To performing Shallow Copy
// Note: Here we are not creating any references.
public DeepAndShollowCopy(int id, String name, List<String>testlist)
{
System.out.println("Shallow Copy for Object initialization");
this.id = id;
this.name = name;
this.testlist = testlist;
}
*/
// To performing Deep Copy
// Note: Here we are creating one references( Al arraylist object ).
public DeepAndShollowCopy(int id, String name, List<String> testlist) {
System.out.println("Deep Copy for Object initialization");
this.id = id;
this.name = name;
String item;
List<String> Al = new ArrayList<>();
Iterator<String> itr = testlist.iterator();
while (itr.hasNext()) {
item = itr.next();
Al.add(item);
}
this.testlist = Al;
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Oracle");
list.add("C++");
DeepAndShollowCopy copy=new DeepAndShollowCopy(10,"Testing", list);
System.out.println(copy.toString());
}
@Override
public String toString() {
return "DeepAndShollowCopy [id=" + id + ", name=" + name + ", testlist=" + testlist + "]";
}
}
为了避免混淆浅复制和简单地为list分配一个新变量名,再添加一点。
“假设我们有:
x = [
[1,2,3],
[4,5,6],
]
这个语句创建了3个列表:2个内部列表和一个外部列表。然后,外部列表的引用在名称x下可用
y = x
没有数据被复制。我们在内存的某个地方仍然有相同的3个列表。所有这一切所做的是使外部列表在名称y下可用,除了它之前的名称x
y = list(x)
or
y = x[:]
这将创建一个与x内容相同的新列表。列表x包含对两个内部列表的引用,因此新列表也将包含对这两个内部列表的引用。只复制了一个列表——外层列表。 现在内存中有4个列表,两个内部列表,一个外部列表,以及外部列表的副本。原始外部列表的名称为x,新的外部列表的名称为y。
内部列表没有被复制!此时,您可以从x或y访问和编辑内部列表!
如果你有一个二维(或更高)的列表,或者任何类型的嵌套数据结构,并且你想对所有内容进行完整复制,那么你想在复制模块中使用deepcopy()函数。你的解决方案也适用于2-D列表,迭代外部列表中的项目,并对每个项目进行复制,然后为所有内部副本构建一个新的外部列表。”
来源:https://www.reddit.com/r/learnpython/comments/1afldr/why_is_copying_a_list_so_damn_difficult_in_python/
在面向对象编程中,类型包括成员字段的集合。这些字段可以按值或引用(即指向值的指针)存储。
在浅复制中,将创建该类型的新实例,并将值复制到新实例中。引用指针也像值一样被复制。因此,引用指向原始对象。对引用存储的成员的任何更改都同时出现在原始和副本中,因为没有对引用的对象进行复制。
在深度复制中,像以前一样复制按值存储的字段,但不复制按引用存储的对象指针。相反,对引用的对象进行深度复制,并存储指向新对象的指针。对这些引用对象所做的任何更改都不会影响该对象的其他副本。
“ShallowCopy”指向与“Source”相同的内存位置。“DeepCopy”指向内存中的不同位置,但内容是相同的。
我从下面几句话中理解到。
浅拷贝将对象的值类型(int, float, bool)字段复制到目标对象中,对象的引用类型(字符串,类等)被复制为目标对象中的引用。在此目标引用类型将指向源对象的内存位置。
深度复制将对象的值和引用类型复制到目标对象的完整新副本中。这意味着值类型和引用类型都将被分配一个新的内存位置。