【问题标题】:passing by reference in __clone在 __clone 中通过引用传递
【发布时间】:2013-11-05 17:26:03
【问题描述】:

在我的__clone 方法中,我通过引用将一个变量分配给另一个变量。在克隆之后,我期望发生的是,当我为一个对象更改此变量时,它会在另一个对象中更改。但这似乎没有发生。

我的代码:

class a {
    var $a;

    function a($var = NULL) {
        if (isset($var)) {
            $this->a = $var;
        }
    }

    function __clone() {
        $temp = new a();
        $temp->a = &$this->a;
        return $temp;
    }
}

$a = new a('test');
$b = clone $a;
$b->a = 'zzz';

echo $a->a;
echo "\r\n";
echo $b->a;

输出是这样的:

test
zzz

我希望它是这样的:

zzz
zzz

【问题讨论】:

    标签: php clone pass-by-reference


    【解决方案1】:

    在调用__clone 方法之前,PHP 已经按值复制了所有属性。 PHP 完成克隆对象后,将调用您的方法。因此,您在该方法中访问的任何属性都已经是值副本。文档指出:

    当一个对象被克隆时,PHP 5 将对该对象的所有属性执行一个浅拷贝。任何引用其他变量的属性都将保持引用。

    克隆完成后,如果定义了 __clone() 方法,则将调用新创建对象的 __clone() 方法,以允许任何需要更改的必要属性。

    你可以在this page的第二段找到这个。

    虽然这不是一个非常漂亮的解决方法,但您可以重命名您的 __clone 方法。然后您可以使用该方法克隆您的对象,尽管这当然不再是实际的克隆,因为它不使用接口进行克隆。

    【讨论】:

      【解决方案2】:

      这是因为__clone() 的返回值被忽略了。您可以看到,如果您将$temp->a = &$this->a; 行更改为$temp->a = 'CLONED';,然后只需将echo $b->a;

      所以你不能改变克隆的结果对象。

      【讨论】:

        【解决方案3】:

        如果我在克隆引用被删除时没有弄错(我认为这是一种内部机制),那么您想要实现的目标会令人困惑,因为您可以简单地这样做:

        $a = new a('test');
        $b = $a;
        $b->a = 'zzz';
        
        echo $a->a;
        echo "\r\n";
        echo $b->a;
        

        引用:“...您想创建另一个对象的新实例,以便副本拥有自己的单独副本。”

        来源:http://php.net/manual/ro/language.oop5.cloning.php

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-14
          • 2015-01-15
          • 2019-07-03
          • 2011-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多