博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP中的浅拷贝和深拷贝
阅读量:7165 次
发布时间:2019-06-29

本文共 2464 字,大约阅读时间需要 8 分钟。

深拷贝和浅拷贝的概念,一般程序员都很熟悉,网上的概念解析也很多。可以查看。

PHP中提供了一种对象复制的操作,clone。语法颇为简单:

$a = clone $b;
这时候就得到a对象就复制了b对象。如果b对象中的成员都是值类型,那也就没什么关系,a对象中的成员和b变量中的成员都是各自占用独立的内存空间。但是由于这个克隆操作是浅拷贝,所以如果b的成员中有引用类型的数据,那么a对象的成员并未真正复制该成员,而是和b对象的成员共享了这一个对象。看下面的示例。
 
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 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 value is updated(this is a) 判断b1的a和b2的a是否为同一对象:1

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

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

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));//序列化然后反序列化
 

转载地址:http://ikmwm.baihongyu.com/

你可能感兴趣的文章
Pentaho6.1 CCC/CDE tool 的Extension points属性详解
查看>>
jdk、tomcat的安装
查看>>
4月4日作业
查看>>
大数据MapReduce 编程实战
查看>>
计算机网络socket编程之UDP
查看>>
高性能的智能日志
查看>>
APScheduler BackgroundScheduler
查看>>
远程连接
查看>>
lvs-nat与lvs-dr配置
查看>>
『中级篇』容器的技术概述(二)
查看>>
Apache awstats安装报错解决过程适合初学者
查看>>
Vsftp安装及配置虚拟用户
查看>>
JVM内存区域
查看>>
DNS的视图功能的简单配置。
查看>>
linux和windows互传文件/用户配置文件和密码配置文件/用户组管理/用户管理
查看>>
通过javascript把图片转化为字符画
查看>>
OpenJPA 一些难搞的查询
查看>>
设置button的样式,使得按钮的图片在上面,文字在图片的下面
查看>>
MySQL之函数、存储过程和触发器
查看>>
完整版的OpenLDAP搭建全过程
查看>>