[转载]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 ...
随机推荐
- f-Strings:一种改进Python格式字符串的新方法
好消息是,F字符串在这里可以节省很多的时间.他们确实使格式化更容易.他们自Python 3.6开始加入标准库.您可以在PEP 498中阅读所有内容. 也称为“格式化字符串文字”,F字符串是开头有一个f ...
- 17,时间模块 time,random模块
表示时间的三种方式 在python中,通常有着三种方式来表示时间:时间戳,元祖,格式化的时间字符串: 1,时间戳(timestamp):通常来说时间戳表示的是从1970年1月1日00:00:00开始按 ...
- appium+python自动化-adb shell模拟点击事件(input tap)
前言 appium有时候定位一个元素很难定位到,或者说明明定位到这个元素了,却无法点击,这个时候该怎么办呢? 求助大神是没用的,点击不了就是点击不了,appium不是万能的,这个时候应该转换思路,换其 ...
- python linux安装anaconda
步骤: 1.在清华大学镜像站中下载anaconda版本:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ https://mirrors.t ...
- 如何使用百度地图API
一.申请密钥 1.先用eclipse创建一个Android工程 2.在百度api官网上申请一个密钥,链接:http://lbsyun.baidu.com/apiconsole/key 二.工程配置 1 ...
- 算法复习——序列分治(ssoj光荣的梦想)
题目: 题目描述 Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯.在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界.保卫这里的平衡与和谐.在那个时 ...
- [TJOI2009]开关 (线段树)
题目描述 现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N.然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[ ...
- SLF4J 简单日志门面 介绍和使用
参考:http://singleant.iteye.com/blog/934593 http://liuzidong.iteye.com/blog/776072 介绍: 简单日记门面(s ...
- 【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】
刚学完 高斯消元,我们来做几道题吧! T1:[BZOJ3143][HNOI2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小 ...
- POJ 2279
线性DP 本题的正解是杨氏矩阵与钩子定理 但是这道题用DP的思想非常好 但是这样会MLE... #include <iostream> #include <cstdio> #i ...