zoukankan      html  css  js  c++  java
  • 深入理解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
    我们从结果可以看出不论是对象本体还是成员变量都是完全不同的东西;

  • 相关阅读:
    P2801 教主的魔法 (分块)
    BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)
    BZOJ_1601_[Usaco2008_Oct]_灌水_(最小生成树_Kruskal)
    BZOJ_1612_[Usaco2008_Jan]_Cow_Contest_奶牛的比赛_(dfs)
    BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)
    BZOJ_1026_[SCOI2009]_windy数_(数位dp)
    BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)
    BZOJ_2194_快速傅立叶之二_(FFT+卷积)
    BZOJ_1615_[Usaco2008_Mar]_The Loathesome_Hay Baler_麻烦的干草打包机_(模拟+宽搜/深搜)
    BZOJ_1626_[Usaco2007_Dec]_Building_Roads_修建道路_(Kruskal)
  • 原文地址:https://www.cnblogs.com/sunke/p/5631073.html
Copyright © 2011-2022 走看看