深度复制和浅复制的区别是什么?


当前回答

除了上述所有定义之外,还有一个最常用的深度复制,位于类的复制构造函数(或重载赋值操作符)中。

浅复制——>是当你没有提供复制构造函数时。在这里,只复制对象,但不复制类的所有成员。

深度复制——>是当您决定在类中实现复制构造函数或重载赋值,并允许复制类的所有成员时。

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
}

其他回答

广度vs深度;从引用树的角度考虑,将对象作为根节点。

浅:

变量A和B指的是不同的内存区域,当B被分配给A时,这两个变量指的是相同的内存区域。后来对其中一个内容的修改立即反映在另一个的内容中,因为它们共享内容。

深:

变量A和B指的是不同的内存区域,当B被分配给A时,A所指向的内存区域中的值被复制到B所指向的内存区域。后来对其中一项内容的修改仍为A或B所独有;内容不共享。

尤其是iOS开发者:

如果B是a的浅拷贝,那么对于原语数据,它就像B = [a assign];对于对象,B = [A retain];

B和A指向同一个内存位置

如果B是a的深层副本,则B = [a copy];

B和A指向不同的内存位置

B的内存地址与A的相同

B和A的含量相同

浅复制-原始和浅复制对象中的引用变量引用公共对象。

深度复制-原始和深度复制对象中的引用变量引用不同的对象。

克隆总是做浅拷贝。

public class Language implements Cloneable{
    
    String name;
    public Language(String name){
        this.name=name;
    }
    
    public String getName() {
        return name;
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

主类如下-

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);
      
      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true
      
      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false
      
} 

以上输出为-

假真假真 假假假

原始物体的任何变化都将反映在浅物体上,而不是在深物体上。

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

输出- ViSuaLBaSiC C

The copy constructor is used to initialize the new object with the previously created object of the same class. By default compiler wrote a shallow copy. Shallow copy works fine when dynamic memory allocation is not involved because when dynamic memory allocation is involved then both objects will points towards the same memory location in a heap, Therefore to remove this problem we wrote deep copy so both objects have their own copy of attributes in a memory. In order to read the details with complete examples and explanations you could see the article C++ constructors.

除了上述所有定义之外,还有一个最常用的深度复制,位于类的复制构造函数(或重载赋值操作符)中。

浅复制——>是当你没有提供复制构造函数时。在这里,只复制对象,但不复制类的所有成员。

深度复制——>是当您决定在类中实现复制构造函数或重载赋值,并允许复制类的所有成员时。

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
}