php深浅拷贝,PHP中的浅拷贝和深拷贝

PHP中提供了一种对象复制的操作,clone。语法颇为简单:$a = clone $b;这时候就得到a对象就复制了b对象。如果b对象中的成员都是值类型,那也就没什么关系,a对象中的成员和b变量中的成员都是各自占用独立的内存空间。但是由于这个克隆操作是浅拷贝,所以如果b的成员中有引用类型的数据,那么a对象的成员并未真正复制该成员,而是和b对象的成员共享了这一个对象。看下面的示例。<?php

class A

{

public $info="this is a";

}

class B

{

public $a;

function __construct()

{

$this->a=new A;

}

public $info="this is b";

}

$b1=new B();

echo "clone操作
";

$b2=clone $b1;

echo"b1的值
";

echo "b1的info:{$b1->info}
";

echo "b1的a的info:{$b1->a->info}
";

echo"b2的值
";

echo "b2的info:{$b2->info}
";

echo "b2的a的info:{$b2->a->info}
";

$b1->info="this value is updated(this is b)";

$b1->a->info="this value is updated(this is a)";

echo"修改b1后,b1的值
";

echo "b1的info:{$b1->info}
";

echo "b1的a的info:{$b1->a->info}
";

echo"修改b1后,b2的值
";

echo "b2的info:{$b2->info}
";

echo "b2的a的info:{$b2->a->info}
";

echo"判断b1的a和b2的a是否为同一对象:" ,$b1->a===$b2->a;

?>运行结果如下:

clone操作

b1的值

b1的info:this is b

b1的a的info:this is ab2的值

b2的info:this is b

b2的a的info:this is a

修改b1后,b1的值

b1的info:this value is updated(this is b)

b1的a的info:this value is updated(this is a)

修改b1后,b2的值

b2的info:this is b

b2的a的info:this value is updated(this is a)

判断b1的a和b2的a是否为同一对象:1

可以看到,修改b1中引用类型a的值后,b2中的a的值也跟着变了。进一步,可以判断出b1的a和b2的a是同一个对象。

和C++一样,php也提供了拷贝构造函数,以此可以自定义复制行为,实现深拷贝。PHP通过在对象的定义中实现__clone()方法来完成拷贝构造函数。这个函数在对象被复制的时候调用。还是之前的代码,修改一下。<?php

class A

{

public $info="this is a";

}

class B

{

public $a;

function __construct()

{

$this->a=new A;

}

public $info="this is b";

public function __clone()

{

echo "拷贝构造函数开始调用
";

$new_object=new A;

$new_object->info=$this->a->info;

$this->a=$new_object;

}

}

$b1=new B();

echo "clone操作
";

$b2=clone $b1;

echo "b1的值
";

echo "b1的info:{$b1->info}
";

echo "b1的a的info:{$b1->a->info}
";

echo"b2的值
";

echo "b2的info:{$b2->info}
";

echo "b2的a的info:{$b2->a->info}
";

$b1->info="this value is updated(this is b)";

$b1->a->info="this value is updated(this is a)";

echo"修改b1后,b1的值
";

echo "b1的info:{$b1->info}
";

echo "b1的a的info:{$b1->a->info}
";

echo"修改b1后,b2的值
";

echo "b2的info:{$b2->info}
";

echo "b2的a的info:{$b2->a->info}
";

echo"判断b1的a和b2的a是否为同一对象:" ,$b1->a===$b2->a;

?>运行完毕后,clone操作

拷贝构造函数开始调用

b1的值

b1的info:this is b

b1的a的info:this is a

b2的值

b2的info:this is b

b2的a的info:this is a

修改b1后,b1的值

b1的info:this value is updated(this is b)

b1的a的info:this value is updated(this is a)

修改b1后,b2的值

b2的info:this is b

b2的a的info:this is a

判断b1的a和b2的a是否为同一对象:

最后可以看到,b1的a和b2的a同一个对象是false,所以打印了一个空字符串。

————————————————————————

上面的方法实现了魔法方法__clone,在这个方法中定义自己的深拷贝方式,这种写法比较麻烦,如果对象修改了,这个方法也得修改。事实上对成员进行深拷贝,可以采用将对象序列化后再还原的方式。这种写法可能性能上有所损失,但是确实最便捷的。PHP中,使用如下语句实现深拷贝:$b2 = unserialize(serialize($b1));//序列化然后反序列化

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值