H5W3
当前位置:H5W3 > 问答 > 正文

PHP对象复制奇怪问题

PHP对象复制奇怪问题

上代码

<?php
class Container
{
public $data;
public $index;
public function __construct($data = null, $index = null)
{
$this->data = $data;
$this->index = $index;
}
}
class Nihao
{
public $head;
public $tail;
public function __construct()
{
$this->head = new Container();
$this->tail = $this->head;
}
public function enqueue($data)
{
$node = new Container($data);
//第一次调用的时候我可以理解,PHP对象复制是浅复制
//但是当第二次调用该方法时,理论上已经被赋值为$node了.
$this->tail->index = $node;
$this->tail = $node;
}
}
$nihao = new Nihao();
echo json_encode($nihao).PHP_EOL;
$nihao->enqueue(0);
echo json_encode($nihao).PHP_EOL;
$nihao->enqueue(1);
echo json_encode($nihao).PHP_EOL;
//{"head":{"data":null,"index":null},"tail":{"data":null,"index":null}}
//{"head":{"data":null,"index":{"data":0,"index":null}},"tail":{"data":0,"index":null}}
//{"head":{"data":null,"index":{"data":0,"index":{"data":1,"index":null}}},"tail":{"data":1,"index":null}}

问题:

我知道PHP的对象复制是浅复制,两个成员对象head和tail指向的是同一个对象,相互影响.

  1. 在第一次调用enqueue(0)的时候已经将tail赋值为一个全新的Container()对象,为什么这一步没有影响到head的值?
  2. 在第二次调用enqueue(1)的时候,退一万步讲,这时候tail已经在上次调用,也就是enqueue(1)的时候被修改了,为什么这次还可以影响到head?
  3. 而且为什么$this->tail->index = $node; 会自定把$node放到head的最后最内层?

回答

浅复制就是引用赋值,用C语言解释就相当于指针,变量的值其实是对象的内存地址而非对象本身。

// head指向了Container对象的内存地址
$this->head = new Container();
// tail指向了head所指向的Container对象的内存地址,所以还是那个Container对象,你误以为tail指向的是head的内存地址,但是head是引用变量
$this->tail = $this->head;

在正式的编码中应该避免重复给成员赋引用值,一个成员应该始终指向同一个对象,也要避免多个成员变量指向同一个引用值。

未经允许不得转载:H5W3 » PHP对象复制奇怪问题

赞 (0)

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址