[转载]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 ...
随机推荐
- 转:Ubuntu下ibus-sunpinyin的安装及翻页快捷键设置!
在windows下,好多人都已经习惯了使用搜狗拼音,到ubuntu下,忽然没有极为顺手的输入法,实为郁闷,但是确实还没有for linux版本的搜狗使用,这是搜狗的商业策略,我们无法掌控,但是,如果你 ...
- win7定时关机
菜单>附件>系统工具>任务计划程序>创建基本任务 alt+r>cmd>shutdown/? 查看相关参数 /l 注销 /s 关机 /r 重启 /g 重启,重启后,重 ...
- search Paths $(SRCROOT)和$(PROJECT_DIR)区别
$(SRCROOT)代表的时项目根目录下 $(PROJECT_DIR)代表的是整个项目 PS:往项目添加文件时,例如.a等,要先showinfinder ,复制到项目中,然后再拖到xcode项目中
- BNUOJ 1055 走迷宫2
走迷宫2 Time Limit: 1000ms Memory Limit: 65535KB 64-bit integer IO format: %lld Java class name: ...
- python pdb模块
参考文件http://pythonconquerstheuniverse.wordpress.com/category/Python-debugger/ 翻译不是一一对应 Debug功能对于devel ...
- 紫书第五章训练2 F - Compound Words
F - Compound Words You are to find all the two-word compound words in a dictionary. A two-word compo ...
- PTA 07-图6 旅游规划 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...
- USACO 2.1 The Castle
题目大意:给你一个城堡让你求有多少房间,最大房间有多大,敲掉一堵墙后最大的房间有多大,敲掉那座墙 思路:比较恶心的bfs题,反正就是bfs使劲敲 /*{ ID:a4298442 PROB:castle ...
- eclipse中AXIS2发布过程
Axis2服务端研究好几个小时,终于解决了 需要下载: 地址1: 可以从镜像站下载: 上海大学开源镜像站 地址2: 链接:从百度网盘下载; 密码:8nwu 其中第二个可以不用下: 解压后 将3,4解压 ...
- Virtual Box 安装过程(卸载Vmware后)
VirtualBox安装前的操作:(或许某些操作不一定有用,但是我是这么做下来的,最后也安装成功了) 步骤一:停止之前安装的vmware的所有服务(如果之前没有安装过虚拟机软件,无需做此操作)VMwa ...