+ -
当前位置:首页 → 问答吧 → 关于OOP的克隆that指针问题

关于OOP的克隆that指针问题

时间:2008-10-14

来源:互联网

PHPer杂志第六期第70页有相关介绍如下:
       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

,有$that?期待高手

作者: weiwei   发布时间: 2008-10-15

php无此关键字、或保留字、或预置工具。。

作者: imkow   发布时间: 2008-10-15

为了准确,我又确认了一次。
杂志上确实大谈特谈“that”,眼前一亮呀。
经过测试,$this确实如书上所说,指的是复制后的对象。
但$that疑似无任何特殊定义,对克隆后对象没有任何作用。只是一个普通变量。
我会继续求证,查一些其他关于php的书,
目前还不能排除是phper杂志上那篇文章作者的认识错误或者知识陈旧(比如是测试版的功能等等)造成的。。。

作者: imkow   发布时间: 2008-10-15

查阅了多本外文书籍,都没有提及that。

但经过一番搜索,发现了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

多谢 imkow 的热心相助,我的搜查结果和你是一样的,所以当时我也是认为$that是其未公开的功能,因为代码中用了“$that->name”并没有报错,而只是没有正常显示,所以我猜可能是这样的。
期待高人指正…………

作者: adam0519   发布时间: 2008-10-15

不是说 $that 一直不好用吗???

作者: MeiWei   发布时间: 2008-10-15

原帖由 adam0519 于 2008-10-15 09:07 发表
多谢 imkow 的热心相助,我的搜查结果和你是一样的,所以当时我也是认为$that是其未公开的功能,因为代码中用了“$that->name”并没有报错,而只是没有正常显示,所以我猜可能是这样的。
期待高人指正…………
是吗?你也认为是未公开的功能。
而我的结论是“$that->name”是作为普通未定义变量,没有特殊含义。
还是不一样的

作者: imkow   发布时间: 2008-10-15

顶,

作者: 海角   发布时间: 2008-10-15

有this又有that, 还有these吗?

作者: myBe   发布时间: 2008-10-15