关于OOP的克隆that指针问题
时间:2008-10-14
来源:互联网
PHP5 定义了一个特殊的方法名“__clone()”方法,是在对象克隆时自动调用的方法,用“__clone()”方法将建立一个与原对象拥有相同属性和方法的对象,如果想在克隆后改变原对象的内容,需要在__clone()中重写原本的属性和方法,“__clone()”方法可以没有参数,它自动包含$this 和$that 两个指针,$this 指向复本,而$that 指向原本;
==================================
下面说问题了
简单代码如下:[php]
class Person{
private static $nextSerial = 0;
private $id;
private $name;
function __construct($name){
$this->name = $name;
$this->id = ++self::$nextSerial;
}
function __clone(){
$this->name = "clone of " . $that->name;
$this->id = ++self::$nextSerial;
}
function getInfo(){
return $this->id . "--" . $this->name;
}
}
$s1 = new Person("Jack");
$s2 = clone $s1;
echo $s1->getInfo() . "<br>";
echo $s2->getInfo() . "<br>";[/php]
输出为:
1--Jack
2--clone of
问题:Person类中的克隆方法,其中$that->name并没有起作用,表现为输出的第二行没有按照本来意愿输出Jack。请问问题出在哪里?到底有无$that指针?难道PHPer杂志出如此大的错误?不应该呀!
多谢各位指教!
作者: adam0519 发布时间: 2008-10-14

作者: weiwei 发布时间: 2008-10-15
作者: imkow 发布时间: 2008-10-15
杂志上确实大谈特谈“that”,眼前一亮呀。
经过测试,$this确实如书上所说,指的是复制后的对象。
但$that疑似无任何特殊定义,对克隆后对象没有任何作用。只是一个普通变量。
我会继续求证,查一些其他关于php的书,
目前还不能排除是phper杂志上那篇文章作者的认识错误或者知识陈旧(比如是测试版的功能等等)造成的。。。
作者: imkow 发布时间: 2008-10-15
但经过一番搜索,发现了that的蛛丝马迹:
网上提到that的除了phper杂志就只有一篇介绍php5的早期文章,可以推断phper文章作者是参考了那篇网文。

而那篇提及that网文的例子像是来自“Changes In PHP5/Zend Engine 2.0”这篇文章。这篇英文发布自5诞生前后,作为手册中的一篇介绍5版新特色的文字。上面的例子也被不少人指出有错
/*
原文
When the developer asks to create a new copy of an object, the Zend Engine will check if a __clone() method has been defined or not. If not, it will call a default __clone() which will copy all of the object's properties. If a __clone() method is defined, then it will be responsible to set the necessary properties in the created object. For convenience, the engine will supply a function that imports all of the properties from the source object, so that they can start with a by-value replica of the source object, and only override properties that need to be changed.
*/
Example
<?php
class MyCloneable {
static $id = 0;
function MyCloneable() {
$this->id = self::$id++;
}
function __clone() {
$this->name = $that->name; //这个例子可能就是那些that的源头。
$this->address = "New York";
$this->id = self::$id++;
}
}
$obj = new MyCloneable();
$obj->name = "Hello";
$obj->address = "Tel-Aviv";
print $obj->id . "\n";
$obj = $obj->__clone();
print $obj->id . "\n";
print $obj->name . "\n";
print $obj->address . "\n";
?>
杂志中例子在 php5.2.6下的输出
Notice: Undefined variable: that in F:\LXH\web\sites\resite\test.php on line 78
Notice: Trying to get property of non-object in F:\LXH\web\sites\resite\test.php on line 78
我的名字叫:张三 性别:男 我的年龄是:20
我的名字叫:我是假的 性别:男 我的年龄是:30
中间的“我是假的”后并没有输出张三,和书上的例样不同。
因此,在没有高人指正之前,我的结论是
1、这个that不存在特殊用法,就是4个字母的变量名。如果有,也是未公开的功能(undocumented feature)。
2、phper杂志上that的说法很可能是以讹传讹,由国人互相传抄发生的错误。
作者: imkow 发布时间: 2008-10-15
期待高人指正…………
作者: adam0519 发布时间: 2008-10-15
作者: MeiWei 发布时间: 2008-10-15
多谢 imkow 的热心相助,我的搜查结果和你是一样的,所以当时我也是认为$that是其未公开的功能,因为代码中用了“$that->name”并没有报错,而只是没有正常显示,所以我猜可能是这样的。
期待高人指正…………
而我的结论是“$that->name”是作为普通未定义变量,没有特殊含义。
还是不一样的
作者: imkow 发布时间: 2008-10-15
作者: 海角 发布时间: 2008-10-15

作者: myBe 发布时间: 2008-10-15
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28