深入理解php的浅复制与深复制

我们经常性赋值给另一个变量,比如说:

class a{

public $pp;

}

//创建一个对象$A;

$A = new a();

$A->pp = "123";

$B = $A;

$B->pp = "456";

同时输出$A,$B的值都是“456“ 充分说明他俩共用一段空间,也就是说$B是$A的一个引用,并没有给B单独开辟一段空间

所以说这是一个浅复制;

我们来看一段深复制

$B = clone $A;

通过关键词我们可以知道是克隆了$A给$B,也就是说给B开辟了单独空间;我们来运行一下,结果如下:

object(a)[1]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ => null
object(a)[2]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ =>
 从结果可以看出来 A和B已经完全不是同一个对象了,这就完成了一个深复制;到这里我们真的可以说完成了一个深复制了吗?NO,如果说我们假设每一个对象都是唯一的,比如说是电脑IP不允许重复,那么我们的深复制会产生两个一样的电脑IP,所以说这样是不行的,这是后就用到了一个php5的class自带的魔术函数__clone();这个函数帮助我们实现深复制,当我们去clone一个对象的时候就调用了类里面的这个函数,我们可以在这个函数中去设置我们的唯一不变量,例如以下代码;若我们没有在clone函数中调用这个setapp,那么会产生一摸一样的成员变量$pp,修改过得代码如下:

<?php
class a{
public $dd = "123";
public $pp=null ;
public function setapp(){
$this->pp = new app();
}
public function getapp(){
return app();
}
function __clone(){
$this->setapp();
}

}
class app{
public $vv=null;
}
$A = new a();
$A->setapp();
$B = clone $A;
var_dump($B);
var_dump($A);

这是我在理解clone时候做的一个演示例子:

类app和a是聚合关系,也就说是一种弱关系型的关联,大家猜一下这个输出结果,我这里先贴上运行结果仅供参考:

object(a)[3]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ =>
    object(app)[4]
      public ‘vv‘ => null
object(a)[1]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ =>
    object(app)[2]
      public ‘vv‘ => null

我们可以清楚的看出这是一个深复制,因为对象的id都不一样,

到这里我们算知道了真正的深复制,可是我们假如有n多个唯一成员,那么我们要一个一个在clone中进行改变吗?

这个是相对比较麻烦的,所以有一个更加简便的方法,那就是利用输入输出流的方式进行深复制;

利用php的serialize的函数我们先进行序列化,然后unserialize函数进行反序列化,读入读出就完全进行了一次复制,

这就是最简便的方式进行深复制,代码如下:

<?php
class a{
public $dd = "123";
public $pp=null ;
public function setapp(){
$this->pp = new app();
}
public function getapp(){
return app();
}
function __clone(){
$this->setapp();
}

}
class app{
public $vv=null;
}
$A = new a();
$A->setapp();
$B = unserialize(serialize($A));
var_dump($B);
var_dump($A);

运行结果如下:

object(a)[3]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ =>
    object(app)[4]
      public ‘vv‘ => null
object(a)[1]
  public ‘dd‘ => 

string

 ‘123‘ (length=3)
  public ‘pp‘ =>
    object(app)[2]
      public ‘vv‘ => null我们从结果可以看出不论是对象本体还是成员变量都是完全不同的东西;
时间: 2024-10-24 17:08:07

深入理解php的浅复制与深复制的相关文章

java基础-浅复制与深复制的理解

浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等.我们可以发现,复制操作后可以得到两份相同的东西,即复制由一变为二了.下面来看一个例子: public class User{ private int age; public int getAge(){ return age; } } User user1 = new User(); User us

原型模式——浅复制与深复制

原型模式涉及一个浅复制和深复制的概念.原型模式可以简单理解为“复制”,但这个复制不是代码的复制.对同一个类,我们可以实例化new三次来“复制”,但如果在初始化的时候构造函数的执行很长,多次实例化就显得效率很低效了.那我们能否只实例化一次,然后“复制”呢? Test test1 = new Test(); Test test2 = test1; Test test3 = test1; 这样写吗?注意这是引用的复制,这实际上还是只有test1一个实例,test2.test3只是复制了其引用而已,如果

也来谈一谈js的浅复制和深复制

1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,undefined,string,number和boolean),这些类型的值本身就存储在栈内存中(string类型的实际值还是存储在堆内存中的,但是js把string当做基本类型来处理 ),不存在引用值的情况. 浅复制和深复制都可以实现在已有对象的基础上再生一份的作用,但是对象的实例是存储在堆内存中然后通

c++中浅复制与深复制

在C++中经常会遇到有关类对象的浅复制与深复制的问题,也是容易出错的地方. 查找了相关资料,有关浅复制与深复制的定义为:对类进行复制的时候按位复制,即把一个对象各数据成员的值原样复制到目标对象中.当类中涉及到指针类型数据成员的时候,往往就会产生指针悬挂问题. class A{ public: int* a; }; A a1; A b1=a1; b1=a1执行的是浅复制,此时a1.a和b1.a指向的是同一个内存地址,如果在析构函数里面有对内存的释放.就会出现内存访问异常.因为一块内存空间会被释放两

黑马程序员--浅析浅复制和深复制的本质

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); 实例浅析oc中的浅复制和深复制的本质 代码段1: #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSMutable

原型模式——浅复制和深复制

设计模式这本书通过对小菜求职复印简历,给我们引出了原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象.其实说简单点就是我们创建好一个模板,然后进行复制,或者将模板修改后进行制-- 由于MemberwiseClone()方法对于字段为值类型的,则对该字段执行逐位复制:如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其复本引用同一对象.所以我们把复制分为浅复制和深复制! 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而其所有的对其他对象的引用都仍然指向

原型模式——浅复制VS深复制

在学习设计模式中的原型模式中遇到了浅复制和深复制这两个陌生的面孔.它们到底是什么意思?浅和深到底是什么意思?还是需要来仔细研究一下的 首先,了解一下原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象.通俗的将其实就是复制. 若收到复制,并不陌生,但是怎么用,我们又该如何用才能达到更加灵活的复制呢? 浅复制: 1.首先要实现最简单的复制,我们用到的一个Clone的方法,具体用法如下: public override Prototype Clone() { return thi

python基础之浅复制与深复制

关于列表.字典.元组的浅复制和深复制,数字和字符串没有浅复制和深复制一说.下面我直接用代码来体现: 1 import copy 2 3 names = ['Cahill','Teenglan','Eric','Peggie','Aalto','Baal','Sadie', 4 'Gage','Hagan','Jack','Kaley','Mabel','Lacy','Nadine','Pace','Amy'] 5 6 #浅复制 7 names2 = names.copy() 8 names2[1

JAVA浅复制与深复制

1.浅复制与深复制概念 ⑴浅复制(浅克隆)     多个变量指向一个对象    被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆)     每个变量指向一个对象,同时对象内包含对象,能复制内部对象    被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复

转载:python中的copy模块(浅复制和深复制)

主要是介绍python中的copy模块. copy模块包括创建复合对象(包括列表.元组.字典和用户定义对象的实例)的深浅复制的函数. ########copy(x)########创建新的复合对象并通过引用复制x的成员来创建x的浅复制.更加深层次说,它复制了对象,但对于对象中的元素,依然使用引用.对于内置类型,此函数并不经常使用.而是使用诸如list(x), dict(x), set(x)等调用方式来创建x的浅复制,要知道像这样直接使用类型名显然比使用copy()快很多.但是它们达到的效果是一样