百科狗-知识改变命运!
--

深拷贝和浅拷贝的异同以及实现方式

小肉包11个月前 (12-16)阅读数 5#综合百科
文章标签对象指针

相同点:

深拷贝和浅拷贝都是用于对复杂数据类型进行复制。

差异:

其区别在于深拷贝是对原数据进行递归复制,并存到一个新地址,从而使新老数据互不影响。

而浅拷贝只是对原数据的地址进行拷贝,从而会使新老数据相互影响。

常用实现方法:

深拷贝:

1.递归复制(全部适用)

function duplicate(obj) {

var newObj = null;

If(obj !== null && typeof(obj)==obj){

newObj=Obj instanceof Array?[]:{};

For (var i in obj){

newObj[i] = duplicate[i];

}

}else{

newObj = obj;

}

return newObj;

}

深拷贝和浅拷贝的异同以及实现方式

2.JSON.stringify(obj);

关于这个方法有一个缺点就是 不能拷贝function和undefine( 在火狐上直接报错error,而在谷歌上会直接忽略掉相关属性) 。因为这是通过把数据转化为字符串的形式赋值给一个新地址。

浅拷贝:

1.函数实现

function simpleDuplicate(obj){

Var newObj ={};

for(var I in obj){

If(obj.hasOwnProperity[i]){

newObj[i] = obj[i];

}

}

return newObj;

}

2.各种赋值、合并删除操作。

在c++中深拷贝与浅拷贝有什么区别?

A:浅拷贝就是成员数据之间的一一赋值:把值赋给一一赋给要拷贝的值。但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件。。当值拷贝的时候,两个对象就有用共同的资源,同时对资源可以访问,这样就会出问题。深拷贝就是用来解决这样的问题的,它把资源也赋值一次,使对象拥有不同的资源,但资源的内容是一样的。对于堆资源来说,就是在开辟一片堆内存,把原来的内容拷贝。

如果你拷贝的对象中引用了某个外部的内容(比如分配在堆上的数据),那么在拷贝这个对象的时候,让新旧两个对象指向同一个外部的内容,就是浅拷贝;如果在拷贝这个对象的时候为新对象制作了外部对象的独立拷贝,就是深拷贝

引用和指针的语义是相似的,引用是不可改变的指针,指针是可以改变的引用。其实都是实现了引用语义。

深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。

COW语义是“深拷贝”与“推迟计算”的组合,仍然是深拷贝,而非浅拷贝,因为拷贝之后的两个对象的数据在逻辑上是不相关的,只是内容相同。

举个简单的例子:

当你实现一个Composite Pattern,你通常都会实现一个深拷贝(如果需要拷贝的话),很少有要求同的Composite共享Leaf的;

而当你实现一个Observer Pattern时,如果你需要拷贝Observer,你大概不会去拷贝Subject,这时就要实现个浅拷贝。

是深拷贝还是浅拷贝,并不是取决于时间效率、空间效率或是语言等等,而是取决于哪一个是逻辑上正确的。

1:没有虚方法和虚基类

2:所有直系基类的copy constructor都是无代价的

3:所有成员的copy constructor都是无代价的

这时它的copy constructor是无代价的,相当于用memcpy实现。

判断它是深拷贝还是浅拷贝,还是要根据类的实现。

大体上来说,深拷贝与浅拷贝的区别主要还是在于指针(或与指针)方面,浅拷贝只是简单的把源对象(这个是指广义的对象,不仅仅单指类的实例)的指针赋值给目标对象,对目标指针的操作就是对源对象的操作,所以在很多情况下,目标对象析构(或跳出其可见域)之后,源对象相关部分也就一同析构了。而深拷贝,是为目标对象重新分配空间,这样可以与源对象的操作分开。

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)