[转载]php中深拷贝浅拷贝
转自:http://cnn237111.blog.51cto.com/2359144/1283163
PHP中提供了一种对象复制的操作,clone。语法颇为简单:
$a = clone $b;
1.浅拷贝
上面的表达式得到a对象就是复制了b对象。如果b对象中的成员都是值类型,那也就没什么关系,a对象中的成员和b变量中的成员都是各自占用独立的内存空间。但是由于这个克隆操作是浅拷贝,所以如果b的成员中有引用类型的数据,那么a对象的成员并未真正复制该成员,而是和b对象的成员共享了这一个对象。看下面的示例。
<?php
class A
{
public $info="this is a";
}
class B
{
public $a;
function __construct()
{
$this->a=new A;
}
public $info="this is b";
}
$b1=new B();
echo "clone操作\n";
$b2=clone $b1;
echo"b1的值\n";
echo "b1的info:{$b1->info}\n";
echo "b1的a的info:{$b1->a->info}\n";
echo"b2的值\n";
echo "b2的info:{$b2->info}\n";
echo "b2的a的info:{$b2->a->info}\n";
$b1->info="this value is updated(this is b)";
$b1->a->info="this value is updated(this is a)";
echo"修改b1后,b1的值\n";
echo "b1的info:{$b1->info}\n";
echo "b1的a的info:{$b1->a->info}\n";
echo"修改b1后,b2的值\n";
echo "b2的info:{$b2->info}\n";
echo "b2的a的info:{$b2->a->info}\n";
echo"判断b1的a和b2的a是否为同一对象:" ,$b1->a===$b2->a, "\n";
输出结果:
clone操作
b1的值
b1的info:this is b
b1的a的info:this is a
b2的值
b2的info:this is b
b2的a的info:this is a
修改b1后,b1的值
b1的info:this value is updated(this is b)
b1的a的info:this value is updated(this is a)
修改b1后,b2的值
b2的info:this is b
b2的a的info:this value is updated(this is a)
判断b1的a和b2的a是否为同一对象:1
可以看到,修改b1中引用类型a的值后,b2中的a的值也跟着变了。进一步,可以判断出b1的a和b2的a是同一个对象。
2.深拷贝
和C++一样,php也提供了拷贝构造函数,以此可以自定义复制行为,实现深拷贝。PHP通过在对象的定义中实现__clone()方法来完成拷贝构造函数。这个函数在对象被复制的时候调用。还是之前的代码,修改一下。
<?php
class A
{
public $info="this is a";
}
class B
{
public $a;
function __construct()
{
$this->a=new A;
}
public $info="this is b"; public function __clone()
{
echo "拷贝构造函数开始调用<br>";
$new_object=new A;
$new_object->info=$this->a->info;
$this->a=$new_object;
}
}
$b1=new B();
echo "clone操作\n";
$b2=clone $b1;
echo "b1的值\n";
echo "b1的info:{$b1->info}\n";
echo "b1的a的info:{$b1->a->info}\n";
echo"b2的值\n";
echo "b2的info:{$b2->info}\n";
echo "b2的a的info:{$b2->a->info}\n";
$b1->info="this value is updated(this is b)";
$b1->a->info="this value is updated(this is a)";
echo"修改b1后,b1的值\n";
echo "b1的info:{$b1->info}\n";
echo "b1的a的info:{$b1->a->info}\n";
echo"修改b1后,b2的值\n";
echo "b2的info:{$b2->info}\n";
echo "b2的a的info:{$b2->a->info}\n";
echo"判断b1的a和b2的a是否为同一对象:" ,$b1->a===$b2->a, "\n";
?>
输出结果:
clone操作
拷贝构造函数开始调用<br>b1的值
b1的info:this is b
b1的a的info:this is a
b2的值
b2的info:this is b
b2的a的info:this is a
修改b1后,b1的值
b1的info:this value is updated(this is b)
b1的a的info:this value is updated(this is a)
修改b1后,b2的值
b2的info:this is b
b2的a的info:this is a
判断b1的a和b2的a是否为同一对象:
最后可以看到,b1的a和b2的a同一个对象是false,所以打印了一个空字符串。
————————————————————————
上面的方法实现了魔法方法__clone,在这个方法中定义自己的深拷贝方式,这种写法比较麻烦,如果对象修改了,这个方法也得修改。事实上对成员进行深拷贝,可以采用将对象序列化后再还原的方式。这种写法可能性能上有所损失,但是确实最便捷的。PHP中,使用如下语句实现深拷贝:
$b2 = unserialize(serialize($b1));//序列化然后反序列化[转载]php中深拷贝浅拷贝的更多相关文章
- java中深拷贝浅拷贝简析
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- 【转】JAVA中的浅拷贝和深拷贝
原文网址:http://blog.bd17kaka.net/blog/2013/06/25/java-deep-copy/ JAVA中的浅拷贝和深拷贝(shallow copy and deep co ...
- Javascript中的浅拷贝和深拷贝
很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用 ...
- python中深拷贝和浅拷贝
python中所谓浅拷贝就是对引用的拷贝,所谓深拷贝就是对对象的资源的拷贝. 首先,对赋值操作我们要有以下认识: 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 ). 修改不可变 ...
- C# 中的浅拷贝与深拷贝
Ø 简介 在 C# 中分为两种数据类型,值类型和引用类型.我们知道,值类型之间赋值是直接将值赋值给另一个变量,两个变量值的改变都互不影响:而引用类型赋值则是将引用赋值给另一个变量,其中一个变量中的成 ...
- python中的浅拷贝,深拷贝
直接引用,间接引用 # 1.列表存储的是索引对应值的内存地址,值会单独的开辟一个内存空间 list = ["a","b"] 内存里面存储的就是list[0],l ...
- c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参
c# 通用类型系统 及变量在 深拷贝 浅拷贝 函数传参 中的深层次的表现 在编程中遇到了一些想不到的异常,跟踪发现,自己对于c#变量在内存上的表现理解有偏差,系统的学习并通过代码实验梳理了各种情况下, ...
- JavaScript之深拷贝&浅拷贝
深拷贝&浅拷贝,说起来都明白,但是说不出所以然.今天就系统的整理下思绪,一点点的将其分析出所以然 废话不多说 浅拷贝 简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以 ...
- 【opencv】imread 赋值 深拷贝浅拷贝
import cv2 import copy import os def filter_srcimg(dstimg): ss=3 srcimg=copy.deepcopy(dstimg) #aa=5 ...
随机推荐
- 16,re模块的常用方法
ret =re.findall('\d+', 'eva123egon4yuan567') print(ret)#返回满足条件的结果 ,放在一个列表里. ret2 = re.search('\d+',' ...
- PYDay10&11&12&13-常用模块:time|datetime|os|sys|pickle|json|xml|shutil|logging|paramiko、configparser、字符串格式化、py自动全局变量、生成器迭代器
1.py文件自动创建的全局变量 print(vars()) 返回值:{'__name__': '__main__', '__package__': None, '__loader__': <_f ...
- cf886d Restoration of string
明确几点 假设有串 ab,那么 a 后头必须是 b,b 前头必须是 a,否则就不是最频繁的了. 不可成环,aba是非法的. #include <iostream> #include < ...
- kali-set
Set 简介 开源的社会工程学利用套件,通常结合metasploit(部分)来使用 更改 /etc/setoolkit下的配置文件 set_config BLEEDING_EDGE="Fal ...
- TOJ 2017: N-Credible Mazes
2017: N-Credible Mazes Time Limit(Common/Java):1000MS/10000MS Memory Limit:65536KByteTotal Subm ...
- HDU-4848 Wow! Such Conquering! 爆搜+剪枝
Wow! Such Conquering! 题意:一个n*n的数字格,Txy表示x到y的时间.最后一行n-1个数字代表分别到2-n的最晚时间,自己在1号点,求到达这些点的时间和的最少值,如果没有满足情 ...
- Android自制rom,为update.zip签名
确认已经安装好openssl openssl genrsa -out key.pem openssl req -new -key key.pem -out request.pem openssl x5 ...
- SoapUI offen used scripts
[ Groovy Step ] //get properties from testCase, testSuite and project in groovy step def testCasePro ...
- 【Luogu】P2759奇怪的函数(二分)
题目链接 看了题解之后突然发现这题简直是水题.然而不看题解就想不出来.为什么呢? len(x)=log10(x)+1 于是二分寻找x. #include<iostream> #includ ...
- 转载:hmm学习网站
http://www.52nlp.cn/hmm-learn-best-practices-seven-forward-backward-algorithm-5