.NET程序員學PHP要注意的坑-OOP 淺複製 深複製 比較對象

<?php
/*
 * PHP OOP
 * 
 *
 */
class SubObject
{
    public $title = "hi,i'm subObject";
}php

class TestDeepCopy
{
    public $subObj;
    public $text = "xxxx";
    public function __construct()
    {
         $this->subObj = new SubObject();   //包含一個子對象用來測試
    }
}
/*
 * 淺複製
 */
$o1 = new TestDeepCopy();
$o2 = $o1;      //淺複製,同C#,2個引用指向同一個對象副本。
//======試試PHP垃圾回收機制==================
$t1 = new TestDeepCopy();
$t2 = new TestDeepCopy();
$t1 = $t2;      //$t1如今變了,原來指向的對象已經沒有人引用了,因此調用了__destruct析構函數
/*
 * 深複製
 * 並非使用clone就是深複製,這和C#道理是同樣的,深複製一般都是要類本身負責完成
 */
$test1 = new TestDeepCopy();
$test2 = clone $test1;          //表面上是2個對象副本了,但內部引用的對象仍是同一個
$test2->subObj->title="yes";    //改變了test2的子對象後, test1的也變了,說明是同一個
var_dump($test1);
var_dump($test2);
/*
 * 深複製方案
 * 1. __clone方法,在克隆一個對象的時候,被調用,利用它能夠作一些:重置克隆出來的新對象的ID號,
 * 畢竟每一個對象的編號要惟一嘛,諸如此類。
 * 也能夠利用它,克隆對象包含的子對象,完成深複製
 * 2. 序列化,反序列化,是遞歸的,因此子對象也一樣深複製,但不會觸發__clone方法,會觸發:
 * __sleep和__wakeup魔術方法
 */
class TestDeepCopy2
{
    public $subObj;
    public $text = "xxxx";
    public function __construct()
    {
         $this->subObj = new SubObject();   //包含一個子對象用來測試
    }函數

    public function __clone()
    {
        echo '__clone  ';
        $this->subObj = new SubObject();
    }
}
//
$d1 = new TestDeepCopy2();
$d2 = clone $d1;
$d2->subObj->title="OK";    //不會影響d1
var_dump($d1);
var_dump($d2);
//序列化方法
$ser1 = new TestDeepCopy2();
$ser2 = unserialize(serialize($ser1));  //沒有觸發__clone方法
$ser2->subObj->title="HOHO";
var_dump($ser1);
var_dump($ser2);
/*
 * 比較對象是否相等:==  ===
 * == 同一類對象的全部成員相等。針對表達式的話,只比較值無論類型
 * === 當且僅當是相同對象的引用。不只考慮值還要考慮類型。
 *     有了自定義__clone後,會打破相等。
 */測試

相關文章
相關標籤/搜索