设计模式——浅复制VS深复制
背景
在学习原型模式的时候,採用了一个差别与其它模式的新方法。採用了“克隆(Clone)方法。通过实现ICloneable接口中的Clone()方法来达到克隆的目的。
代码实现过程中,存在了我们所说的浅复制和深复制,以下看看有什么差别。
内容
代码实现
简历浅复制实现:
<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 浅复制
{
class Program
{
static void Main(string[] args)
{
Resume a = new Resume("大鸟");
a.SetPersonalInfo("男", "29");
a.SetWorkExperience("1992-2002", "XX公司"); Resume b = (Resume)a.Clone();
b.SetWorkExperience ("1992-2002","YY公司"); Resume c=(Resume )a.Clone ();
c.SetPersonalInfo ("男","24");
c.SetWorkExperience ("1995-2200","ZZ企业"); a.Display ();
b.Display ();
c.Display ();
Console .Read ();
}
}
//工作经历类
class WorkExperience
{
private string workDate;
public string WorkDate
{
get { return workDate; }
set { workDate = value; }
} private string company;
public string Company
{
get { return company; }
set { company = value; } } } //简历类
class Resume:ICloneable
{
private string name;
private string sex;
private string age; private WorkExperience work;//引用“工作经历”对象 public Resume (string name )
{
this.name = name;
work = new WorkExperience();//在“简历”类实例化时间时实例化“工作经历”;
}
//设置个人信息
public void SetPersonalInfo(string sex, string age)
{
this.sex =sex ;
this .age =age ; } //设置工作经历
public void SetWorkExperience (string workDate,string company)
{
//调用此方法时,给对象的两属性赋值;
work.WorkDate = workDate;
work.Company = company;
}
//显示
public void Display()
{
Console.WriteLine("{0} {1} {2}", name, sex, age);
Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);//显示时,显示“工作经历”的两属性的值。 } public Object Clone()
{
return (Object)this.MemberwiseClone();
}
}
}
</span></span>
结果为:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
简历深复制实现:
<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">//作者:周丽同
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 简历的深复制实现
{
class Program
{
static void Main(string[] args)
{
Resume a = new Resume("大鸟");
a.SetPersonalInfo("男", "29");
a.SetWorkeExperience("1998-2000", "XX公司"); Resume b = (Resume)a.Clone();
b.SetWorkeExperience("1998-2006", "YY公司"); Resume c = (Resume)a.Clone();
c.SetPersonalInfo("男", "24");
c.SetWorkeExperience("1998-2003", "ZZ企业"); a.Display();
b.Display();
c.Display(); Console.Read();
}
} //修改的地方是:让工作经历也实现ICloneable接口
//工作经历类
class WorkExperience:ICloneable
{
private string workDate;
public string WorkDate
{
get { return workDate; }
set { workDate = value; }
}
private string company;
public string Company
{
get { return company; }
set { company = value; }
} public Object Clone()
{
return (Object)this.MemberwiseClone();//“工作经历”类实现克隆方法。
}
} //简历类
class Resume:ICloneable
{
private string name;
private string sex;
private string age;
private WorkExperience work; public Resume (string name)
{
this.name = name;
work = new WorkExperience();
}
private Resume (WorkExperience work)
{
//提供克隆(Clone)方法调用的私有构造函数,以便克隆“工作经历”的数据;
this.work = (WorkExperience)work.Clone(); } //设置个人信息
public void SetPersonalInfo(string sex,string age )
{
this.sex = sex;
this.age = age;
}
//设置工作经历 public void SetWorkeExperience(string workDate,string company)
{
work.WorkDate = workDate;
work.Company = company;
}
//显示 public void Display()
{
Console.WriteLine("{0} {1} {2}", name, sex, age);
Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
} public Object Clone()
{
//调用私有的构造函数,让“工作经历”克隆完毕。然后再给这个“简历”对象的相关字段赋值。
//终于返回一个深复制的简历对象。
Resume obj = new Resume(this.work);
obj.name = this.name;
obj.sex = this.sex;
obj.age = this.age;
return obj;
}
} }</span></span>
结果是:
从上面的样例能够看出为什么对于值类型的对象。在克隆的时候能够轻易的复制过来,可是对于引用类型的。在克隆的时候复制过来的仅仅是引用对象,而引用对象的数据是不会复制过来的。这里涉及到了什么是值类型和引用类型。它们在内存中是怎么“走的”。且看且分析:
|
值类型 |
引用类型 |
|
|
类型 |
结构体;数值类型(整型);浮点型。decimal型;bool型;枚举;可空类型; |
数组。用户定义的类。接口;托付; Object类型;字符串类型; |
|
能否够包括null值 |
否 |
是 |
|
内存分配 |
分配在栈中 |
分配在堆中 |
|
主要职责 |
存储数据 |
传递引用(相当于指针) |
|
适用场合 |
该类型的共同拥有接口全然由一些数据成员存取属性定义; 永远不可能又子类。 不具有多态行为; |
具有多态行为; 用于定义应用程序的行为; |
浅复制和深复制含义
在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:
浅复制:
深复制:
通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="font-size:18px; font-family:KaiTi_GB2312; text-align:center">
小结
设计模式——浅复制VS深复制的更多相关文章
- 设计模式-原型模式(Prototype)【重点:浅复制与深复制】
讲故事 最近重温了一下星爷的<唐伯虎点秋香>,依然让我捧腹不已,幻想着要是我也能有一名秋香如此的侍女,夫复何求呀,带着这个美好的幻想沉沉睡去... 突然想到,我是一名程序猿呀,想要什么对象 ...
- iOS 浅复制和深复制的深层理解,含示例
转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...
- java基础-浅复制与深复制的理解
浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...
- iOS 浅复制、深复制、完全复制的知识点梳理验证(附加归档解档)
在之前转载的一片文章中,文中对浅复制和深复制进行了详细的解读,同时还提到了深复制(one-level-deep copy).完全复制(true copy)的概念,并指出iOS开发中的深复制是单层深赋值 ...
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...
- js中的浅复制和深复制
浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...
- 也来谈一谈js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...
随机推荐
- 寻找道路(NOIP2014)神奇之题。。
原题传送门 这道题嘛.. 首先根据题目,我们要先知道哪些点能够到达终点.(反向BFS) 然后我们再求最短路的途中,必须随时判断周围的点是否被第一次BFS标记过.. 所以再来一次BFS. 数组记得清零, ...
- 请求路径@PathVariable与请求参数@RequestParam的区别
转自:http://www.iteye.com/problems/101566: http://localhost:8080/Springmvc/user/page.do?pageSize=3& ...
- jQuery的动画方法
/* animate参数: 参数一:要改变的样式属性值,写成字典的形式 参数二:动画持续的时间,单位为毫秒,一般不写单位 参数三:动画曲线,默认为‘swing’,缓冲运动,还可以设置为‘linear’ ...
- cmake add_executable 与 include_directories
在cmake里add_executable里如果没有包含.cpp文件,该.cpp文件就不适用include_directories包含文件
- C# web server的开发流程
http://blog.csdn.net/h0322/article/details/4776819
- CF986A Fair【图论/BFS】
[题意]: 有些公司将在Byteland举办公平的会议.Byteland的n个城镇,m条两镇之间的双向道路.当然,你可以使用道路从任一个城镇到达任何城镇. 有k种商品产自Byteland,并且每个城镇 ...
- Apache优化建议
Apache是Web服务器软件,它最常见是搭配PHP开发语言去使用.今天,小编根据Apache官方手册再结合实际,整理出下面这些优化建议,希望对大家的Apache服务器的运行效率有效果. 1.控制Ma ...
- c++ —— .bat 对拍
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...
- [NOIP模拟赛][贪心]奶牛晒衣服.
奶牛晒衣服(dry) [问题描述] 在熊大妈英明的带领下,时针和它的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任.洗 ...
- How to: Launch the Debugger Automatically
Sometimes, you may need to debug the startup code for an application that is launched by another pro ...