.NET程序员学PHP要注意的坑-OOP 浅复制 深复制 比较对象

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

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后,会打破相等。
 */

转载于:https://my.oschina.net/SethFeng/blog/538947

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值