浅复制(Shallow Copy)与深复制(Deep Copy)

复制:对象的复制是生成一个与指定对象完全一样的新对象,实现的方式根据定义可以知道,新建一个类型相同的对象,然后复制原对象的每一个成员和字段。

 浅复制:

    class Program
    {
        static void Main(string[] args)
        {
            ClassA A = new ClassA();
            CloneObj clone = new CloneObj();
            ClassA newA= clone.CloneA(A);
        }
    }

    public class ClassA
    {
        public Int32 AValue = 100;
    }

    public class ClassB
    {
        public Int32 BValue = 200;
    }

    public class CloneObj
    {
        public ClassA CloneA(ClassA obj)
        {
            ClassA newAobj = new ClassA();
            newAobj.AValue = obj.AValue;
            return newAobj;
        }
    }

上面的CloneObj的CloneA方法就是一个浅复制ClassA对象,修改代码:

    class Program
    {
        static void Main(string[] args)
        {
            ClassA A = new ClassA();
            CloneObj clone = new CloneObj();
            ClassA newA= clone.CloneA(A);
        }
    }

    public class ClassA
    {
        public Int32 AValue = 100;
        public ClassB objB;
        public ClassA()
        {
            objB = new ClassB();
        }
    }

    public class ClassB
    {
        public Int32 BValue = 200;
    }

    public class CloneObj
    {
        public ClassA CloneA(ClassA obj)
        {
            ClassA newAobj = new ClassA();
            newAobj.AValue = obj.AValue;
            newAobj.objB = obj.objB;
            return newAobj;
        }
    }

这里ClassA里面包含了引用类型的ClassB对象,这里复制的ClassA对象,如下图:

上面这种方式就是“浅复制(Shallow Copy)”,这里可以在调试时测试下,看看A里面objB的地址和通过复制方法出来的newA的objB的地址:

地址完全一样

浅复制是.NET默认的对象复制方式,Object类提供的Memberwise方法浅复制一个对象。实现深复制,也就是上面的图中,不是共用一个ClassB对象,而是完全创建一个新的ClassB对象。这需要实现ICloneable接口.如下:

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassA A = new ClassA();
            CloneObj clone=new CloneObj();
            ClassA newA = clone.CloneA(A);

        }
    }

    public class ClassA:ICloneable
    {
        public Int32 AValue = 100;
        public ClassB objB;
        public ClassA()
        {
            objB = new ClassB();
        }

        object ICloneable.Clone()
        {
            ClassA objA = new ClassA();
            objA.AValue = this.AValue;
            objA.objB = (this.objB as ICloneable).Clone() as ClassB;
            return objA;
        }
    }

    public class ClassB:ICloneable
    {
        public Int32 BValue = 200;

        object ICloneable.Clone()
        {
            ClassB objB = new ClassB();
            objB.BValue = this.BValue;
            return objB;
        }
    }

    public class CloneObj
    {
        public ClassA CloneA(ClassA obj)
        {
            //ClassA newAobj = new ClassA();
            //newAobj.AValue = obj.AValue;
            //newAobj.objB = obj.objB;
            ClassA newAobj = (obj as ICloneable).Clone() as ClassA;
            return newAobj;
        }
    }

}

测试结果如图:

这里完成了深复制

对象序列化

对象复制比较简单的方式是序列化,将类标记为[Serializable]。对象序列化主要解决的是对象状态的保存问题,这里所说的“对象状态”是指某一时刻对象拥有的字段值的集合。

对象的序列化:将一个内存的对象保存到流中,并在需要时从流中读取数据重建对象的过程称为“对象序列化”和“反序列化”

流:代表一连串有顺序的二进制数据。

利用序列化进行对象的复制——深复制

    [Serializable]
    class MyClass
    {
        public int Index = 1;
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass obj = new MyClass();
            //创建一个内存流对象
            using (MemoryStream ms = new MemoryStream())
            {
                IFormatter formator = new BinaryFormatter();
                formator.Serialize(ms, obj);  //将对象序列化到内存流中 

                //克隆100个对象
                for (int i = 0; i < 100; i++)
                {
                    ms.Seek(0, SeekOrigin.Begin);//回到流的开头
                    obj = (formator.Deserialize(ms) as MyClass); //反序列化对象
                    obj.Index += i;   //设置对象字段
                    Console.WriteLine("对象{0}已创建。", obj.Index);
                }
            }
            Console.ReadKey();
        }
    }

原理是将对象序列化到流中,然后从流中创建对象(批量),从而实现了深复制。

读书笔记《.NET4.0面向对象编程漫谈》作者:金旭亮老师

时间: 2024-10-16 05:40:50

浅复制(Shallow Copy)与深复制(Deep Copy)的相关文章

iOS开发之深复制和浅复制

1.概述 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 如下图: 再简单些说:浅复制就是指针拷贝:深复制就是内容拷贝.   2.集合的浅复制 (shallow copy) 集合的浅复制有非常多种方法.当你进行浅复制时,会向原始的集合发送retain消息,引用计数加1,同时指针被拷贝到新的集合. 现在让我们看三个浅复制的例子:   ? 1 2 3 4 NSArray *shallowCopyArray

php中浅复制与深复制的例子

周末闲来无事看到了原型模式,其中谈到了浅复制和深复制,想到PHP中的对应赋值.克隆以及克隆是浅复制还是深复制. 先来看看赋值,例如有一个简历类,有身高和体重两个属性: class Resume  {     public $height;     public $weight;       public $workExperience; } $ResumeA = new Resume(); $ResumeB = $ResumeA; 此时实例化了一个Resume类并赋值给了$ResumeA变量,然

举例区分Python中的浅复制与深复制

  这篇文章主要介绍了举例区分Python中的浅复制与深复制,是Python入门学习中的重要知识,需要的朋友可以参考下 copy模块用于对象的拷贝操作.该模块非常简单,只提供了两个主要的方法: copy.copy 与 copy.deepcopy ,分别表示浅复制与深复制.什么是浅复制,什么是深复制,网上有一卡车一卡车的资料,这里不作详细介绍.复制操作只对复合对象有效.用简单的例子来分别介绍这两个方法. 浅复制只复制对象本身,没有复制该对象所引用的对象. ? 1 2 3 4 5 6 7 8 9 1

C++深复制和浅复制

对象的复制   对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=88; int b=a; double f=3.12; double d(f); 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种数据成员.下面看一个类对象复制的简单例子. #include <iostream> using namespace std; class Test { private: int a,b; public: Test(int x, int y) //提供的形式参数,是为了给

Java Generic Deep Copy

原文:http://www.genericdeepcopy.com/ Java Generic Deep Copy  简介: Generic Deep Copy 是一个用于深度拷贝的java实用程序.这些被拷贝的对象不需要去实现Serializable,Cloneable或者任何其他的接口.基本上,这个程序可以深度拷贝任何java对象.在很多场合,使用它可以节省时间和精力. 使用场景: 无法进行系列化(non Serializable)的类并且它们来自第三方jars库,因此对应的源码无法改变:

android 浅复制和深复制-Java Generic Deep Copy 篇

关于Java Generic Deep Copy 在java中的应用和注意事项,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7039425 而关于在android程序中通过clone方法来进行浅复制和深复制,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7036818 众所周知,android上层使用的是java语言,因此理论上于Java Generic De

Java中的深拷贝(深复制)和浅拷贝(浅复制)介绍_java

深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java.虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑. 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象.深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象.举例来说更加清楚:对象A1中包含对B1的引用

java中对象的浅复制和深复制笔记

在面向对象的语言中,如Java/Python,对象的复制有两种形式:浅复制和深复制 一.浅复制    浅复制只是将原对象的引用备份了一份给新的变量,实际两者指向的是同一个对象.在Python中,字典.列表.元祖等都是对象类型 >>> person=['name',['savings',100.00]] >>> hubby=person[:] >>> wifely=list(person) >>> [id(x) for x in per

浅析:对象的浅复制和深复制

问题描述 在面向对象的语言中,如Java/Python,对象的复制有两种形式:浅复制和深复制一.浅复制浅复制只是将原对象的引用备份了一份给新的变量,实际两者指向的是同一个对象.在Python中,字典.列表.元祖等都是对象类型>>> person=['name',]>>> hubby=person>>> wifely=list(person)>>> >>>person是一个列表对象,分割之后赋给hubby,将perso