一段shallowCopy和deepCopy的认识
:什么是浅拷贝(shallow copy)和深拷贝(deep copy)?
A:
浅拷贝就是成员数据之间的一一赋值:把值一一赋给要拷贝的值。但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件。。当值拷贝的时候,两个对象就有用共同的资源,同时对资源可以访问,这样就会出问题。深拷贝就是用来解决这样的问题的,它把资源也赋值一次,使对象拥有不同的资源,但资源的内容是一样的。对于堆资源来说,就是在开辟一片堆内存,把原来的内容拷贝。
如果你拷贝的对象中引用了某个外部的内容(比如分配在堆上的数据),那么在拷贝这个对象的时候,让新旧两个对象指向同一个外部的内容,就是浅拷贝;如果在拷贝这个对象的时候为新对象制作了外部对象的独立拷贝,就是深拷贝
引用和指针的语义是相似的,引用是不可改变的指针,指针是可以改变的引用。其实都是实现了引用语义。
深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。
COW语义是“深拷贝”与“推迟计算”的组合,仍然是深拷贝,而非浅拷贝,因为拷贝之后的两个对象的数据在逻辑上是不相关的,只是内容相同。
Q:什么情况下使用浅拷贝什么时候使用深拷贝?
A:
无论深浅,都是需要的。当深拷贝发生时,通常表明存在着一个“聚合关系”,而浅拷贝发生时,通常表明存在着一个“相识关系”。
举个简单的例子:
当你实现一个Composite Pattern,你通常都会实现一个深拷贝(如果需要拷贝的话),很少有要求同的Composite共享Leaf的;
而当你实现一个Observer Pattern时,如果你需要拷贝Observer,你大概不会去拷贝Subject,这时就要实现个浅拷贝。
是深拷贝还是浅拷贝,并不是取决于时间效率、空间效率或是语言等等,而是取决于哪一个是逻辑上正确的。
Q:在C++中default constructor对对象进行的是怎样的拷贝动作?
A:
再纠正一个概念:default constructor是不负责拷贝动作的,我想你说的应该是指implicitly-declared copy constructor。它会调用所有直系基类的copy constructor和有成员的copy constructor,并且复制vtpr。如果一个类:
1:没有虚方法和虚基类
2:所有直系基类的copy constructor都是无代价的
3:所有成员的copy constructor都是无代价的
这时它的copy constructor是无代价的,相当于用memcpy实现。
判断它是深拷贝还是浅拷贝,还是要根据类的实现。比如如果它有一个用原生指针指针实现的对象引用,或是用boost::shared_ptr等引用分享所有权的智能指针实现的对象引用,则这个拷贝是浅拷贝;如果是用copy_ptr这种实现了深拷贝的智能指针实现的对象引用,就是深拷贝了。
一段shallowCopy和deepCopy的认识的更多相关文章
- 玩转JavaScript OOP[4]——实现继承的12种套路
概述 在之前的文章中,我们借助构造函数实现了"类",然后结合原型对象实现了"继承",并了解了JavaScript中原型链的概念. 理解这些内容,有助于我们更深入 ...
- C# 对象的深复制和浅复制
2019年第一篇博客,好吧,又大了一岁了,继续加油吧. 正文: C# 中的对象,众所周知是引用类型,那么如何复制对象Object呢,我们来看看下面这段代码: public class User { p ...
- Object.MemberwiseClone
[Object.MemberwiseClone] Creates a shallow copy of the current Object. protected object MemberwiseCl ...
- hx计算机基础
参考:http://python.jobbole.com/82294/ https://www.jianshu.com/p/aed6067eeac9 1. 操作系统基础题 1)在32位操作系统下,系统 ...
- javascript中的浅拷贝ShallowCopy与深拷贝DeepCopy
拷贝,在js中,分为浅拷贝和深拷贝.这两者是如何区分的呢?又是如何实现的呢? 深浅拷贝的区分 首先说下,在js中,分为基础数据类型和复杂数据类型, 基础数据类型:Undefined.Null.Bool ...
- 日积(Running)月累(ZSSURE):Task之Cancel、OpenAccess之Delete及fo-dicom之DeepCopy、
题记: 最近看了一篇关于架构方面的良心长文你的架构是怎样一步步腐化的?,文中字字句句道出了诸多从业者.初创企业,以及BAT都会遇到的问题,细细品读后认为工作生活中的诸多情况皆如此,都会有一个体量由小到 ...
- 从python中copy与deepcopy的区别看python引用
讨论copy与deepcopy的区别这个问题要先搞清楚python中的引用.python的内存管理. python中的一切事物皆为对象,并且规定参数的传递都是对象的引用.可能这样说听起来比较难懂,对比 ...
- Python的传值和传址与copy和deepcopy
1.传值和传址 传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针).他们的区别是如果函数里面对传入的参数重新赋值,函数外的全局变量是否相应改变,用传值传入的参数是不会 ...
- Python-copy()与deepcopy()区别
http://blog.csdn.net/qq_32907349/article/details/52190796 学习过程中发现copy()和deepcopy()这对好基友实在是有点过分,搞的博主就 ...
随机推荐
- 基于SSM的单点登陆03
TbUser.java和TbUserExample.java,TbUserMapper.java,TbUserMapper.xml由mybatis框架生成. generatorConfig.xml & ...
- list— 把数组中的值赋给一组变量
(PHP 4, PHP 5, PHP 7) list — 把数组中的值赋给一组变量 array list ( mixed $var1 [, mixed $... ] ) 像 array() 一样,这不 ...
- Linux 系统密码破解
(一)CentOS Linux 系统密码破解 1.在grub选项菜单按E进入编辑模式 2.编辑kernel那行 /init 1 (或/single) 3.按B重启 4.进入后执行下列命令 root@# ...
- 基于主主复制的mysql双机热备+keepalived实现高可用性
- Apache Phoenix的子查询
Phoenix现在支持在WHERE 和FROM 中使用子查询.子查询可以被指定在很多地方,比如 IN/NOT IN, EXISTS/NOTEXISTS等. Subqueries with INor N ...
- HDU 5992 kd-tree
还记得青岛的时候和蕾姐讨论了近三个小时也不知道这是什么东西 后来发现是kdtree 于是拖到寒假才补这个算法 写完几道模板题发现多维的kdtree查找最近也是很简单的拓展 于是很快1A了这道题 它真的 ...
- 解决Pycharm中matplotlib画图出错问题(AttributeError: module 'matplotlib' has no attribute 'verbose')
最近在Linux中使用pycharm过程中使用matplotlib无法画图,总是提示错误 /usr/bin/python3. /home/leo/PycharmProjects/untitled1/E ...
- HDU3047 Zjnu Stadium
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 总结django知识点
一.视图函数: 请求对象-----------request: 1.HttpRequest.body: 请求原数据 2.HttpRequ ...
- Django---model基础(单表)
ORM 一.映射关系: 表名<--------------->类名 字段<-------------->属性 表记录& ...