zoukankan      html  css  js  c++  java
  • php引用复制,浅复制clone和深复制

    1.引用复制

    <?php 
    class  a {
        public $info=0;
    }
    $a=new a();
    $b=$a;  //引用赋值
    $a->info="10";
    echo $a->info."<br>";
    echo $b->info."<br>";
    die; 

    结果如下:

     

    2.浅复制clone

    <?php 
    class  a {
        public $info=0;
    }
    $a=new a();
    $b=clone $a;  //clone
    $a->info="10";
    echo $a->info."<br>";
    echo $b->info."<br>";
    die;
    

      结果如下

     

    那么为什么叫浅复制呢,因为它只能复制类里面的属性和方法,如果类里面的属性和方法用到的其他的对象,那么复制过去的也是引用复制,如下:

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }
    }
    $a=new mytest(10);
    $b= clone $a;   //clone
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象中的属性可有变化
    echo $b->test->bianliang."<br>";
    die;
    

      结果如下:

     这说明 $b对象中的$test对象指向的是$a对象的$test对象,那么如何避免呢

    用__clone魔术方法把类中用的其他对象重新clone一下

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }    
        public function __clone(){
            $this->test=clone $this->test;   //克隆一下这个对象,不然指向的还是同一个对象
        } 
    }
    $a=new mytest(10);
    $b= clone $a;   //clone
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
    echo $b->test->bianliang."<br>";
    die;

    结果如下

     3.深复制

       深复制,可以利用上面的魔术方法__clone()或者利用序列化和反序列化的方法

    <?php 
    class mybianliang {
        public $bianliagn=0;
        public function __construct($bianliang){
            $this->bianliang=$bianliang;
        }
        public function changebianliang($bianliang2){
            $this->bianliang=$bianliang2;
        }
    }
    class  mytest {
        public $test=0;
        public function __construct($bianliang){
            $this->test=new mybianliang($bianliang);
        }
    
    }
    
    $a=new mytest(10);
    $b = unserialize(serialize($a));   //序列化和反序列化
    echo $a->test->bianliang."<br>";  
    $a->test->changebianliang(20);       //改变a对象中test对象中的属性值,看看b对象中的test对象可有变化
    echo $b->test->bianliang."<br>";
    die;
    

      执行结果

  • 相关阅读:
    pku2992 Divisors
    pku3090 Visible Lattice Points
    pku3615 Cow Hurdles
    禁止 verifier.dll 监控程序
    运行ogreSDK的samples
    #pragma pack(n) 啥时候可以不再忘记?
    游戏开发流程图。
    希望可以尽快的写篇自己的成果。
    windows与OS X下的std::string
    VS2008鼠标右键不灵敏,TFS的Local Path无法打开对应文件夹
  • 原文地址:https://www.cnblogs.com/flyyu/p/14119974.html
Copyright © 2011-2022 走看看