读书频道 > 网站 > 网页设计 > PHP编程实战
1.4 复制、克隆和比较对象
14-10-31    奋斗的小年轻
收藏    我要投稿   

本文所属图书 > PHP编程实战

本书主要内容包括:PHP 5 3 面向对象编程、PHP 的一些新特性、如何编写基于SQL 和NoSQL 的数据库交互程序、如何使用流行的PHP 相关工具、如何编写社交媒体应用程序,并介绍了NoSQL 数据存储以及为云生态编立即去当当网订购
 
在本章的开头,我讨论过什么是类以及如何创建和处理复杂对象。现在该讨论内部对象处理的一些内容了。当使用如$x=new class(....)的命令来创建一个对象时,变量$x是对象的一个引用。执行像$x=$y一样的语句时,会发生什么呢?答案很简单:句柄$x所指向的原始对象被销毁,同时调用其析构函数,并且$x指向对象$y。如代码清单1-7所示。
 
代码清单1-7 当执行$x=$y时 
<?php  
# 浅复制示例
class test3 {  
    protected $memb; 
    function __construct($memb) {  
        $this->memb = $memb;  
    }  
    function __destruct() {  
        printf("Destroying object %s...\n", $this->memb);  
    }  
}  
$x = new test3("object 1");  
$y = new test3("object 2");  
print "Assignment taking place:\n";  
$x = $y;  
print "End of the script\n";  
?> 
 
当执行时,产生如下输出。
Assignment taking place:
Destroying object object 1...
End of the script
Destroying object object 2...
 
当执行$x=$y时,对象1在赋值过程中被破坏。那为何对象2也被破坏呢?这个问题的答案很简单:只要对象出了它的作用域,都会调用析构函数。当脚本执行结束,所有幸存的对象将跑出它们的作用域,这样每个对象都将调用其析构函数一次。这也是为何封闭两个print命令之间赋值的原因。此外请注意,尽管事实上底层对象$x和$y有两个引用,但是析构函数只执行一次。针对每一个对象,而不是每一个引用,析构函数被调用一次。这种复制对象的方式称为浅复制(shallow copy),因为只是改变了引用,从来没有创建真正的对象副本。
 
除了浅复制,还有深复制(deep copy),深复制会创建一个新的对象。这个深复制是使用克隆操作完成的,如代码清单1-8所示。
 
代码清单1-8 深复制使用克隆操作
<?php 
# 深复制示例
class test3a { 
    protected $memb; 
    protected $copies; 
    function __construct($memb, $copies = 0) { 
        $this->memb = $memb; 
        $this->copies = $copies; 
    } 
    function __destruct() { 
        printf("Destroying object %s...\n", $this->memb); 
    } 
    function __clone() { 
        $this->memb.= ":CLONE"; 
        $this->copies++; 
    } 
    function get_copies() { 
        printf("Object %s has %d copies.\n", $this->memb, $this->copies); 
    } 
$x = new test3a("object 1"); 
$x->get_copies(); 
$y = new test3a("object 2"); 
$x = clone $y; 
$x->get_copies(); 
$y->get_copies(); 
print "End of the script, executing destructor(s).\n"; 
?> 
 
深复制在$x=clone $y行完成。但执行该行代码时,对象$y的一个新副本被创建,同时,调用__clone函数,是为了有助于安排新副本为脚本所需要的形式。这个脚本的输出如下所示。
Object object 1 has 0 copies.  
Destroying object object 1...  
Object object 2:CLONE has 1 copies.  
Object object 2 has 0 copies.  
End of the script, executing destructor(s).  
Destroying object object 2...  
Destroying object object 2:CLONE... 
 
在$x里,新创建的副本有一个成员值Object object 2:CLONE,并且副本份数设置为1,这是__clone方法执行的结果。另外请注意,构造函数执行两次,一个为原来的副本,一个为克隆的副本。克隆没有像引用赋值那样频繁使用,但是当需要时,也可以频繁使用克隆。
 
对象是如何比较的呢?根据比较的标准,有几种情况需要考虑。究竟何时称两个变量$x和$y是“相等的”?下面是三种逻辑同样有效的情况。
 
同一类对象的所有成员是相等的。
 
对象是同一类相同对象的引用。
 
使用其他用户规定的标准。
 
标准相等运算符==用于测试第一种情形。当且仅当$x和$y相应的成员彼此都相等时,表达式$x==$y成立。
 
第二种情形,即$x和$y是相同对象的引用,通过特殊运算符测试===(三个连续等号)。当且仅当$x和$y是相同对象的引用时,表达式$x===$y成立。要注意的是,通常的赋值,如$x=$y,将有表达式$x===$y返回true,而克隆操作将打破相等。如果没有自定义的__clone方法,原有的和克隆的将是相等的,就像==运算符定义的相等一样。
 
关于第三种情形,即一个对相等自定义形成的定义,可以做些什么呢?在这种情况下,必须写一个自定义函数,并比较返回值。当编写的函数提取一个特定类的参数时,它很可能通过在正式参数名称前面列出参数类型,迫使参数为所要求的类型。如下所示。
function test_funct(test3a $a) {….}
 
在这种情况下,要求参数$a为test3a类型。这只能针对对象类型和数组,通过输入关键词array而不是对象名称来完成。PHP 5仍是一种不太支持类型的语言,总是强制参数类型为经典类型,如PHP就不支持int。
 
点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站