首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按引用计算,对象的值?

按引用计算,对象的值?
EN

Stack Overflow用户
提问于 2011-04-06 16:43:50
回答 3查看 101关注 0票数 0

我正在通过阅读PHP官方文档来学习面向对象的php。

首先:

代码语言:javascript
复制
class SimpleClass
  {
      // property declaration
      public $var = 'a default value';

      // method declaration
      public function displayVar() {
      echo $this->var;
      }
  }

第二:

代码语言:javascript
复制
  $instance = new SimpleClass();

  $assigned   =  $instance;
  $reference  =& $instance;

  $instance->var = '$assigned will have this value';

  $instance = null; // $instance and $reference become null

  var_dump($instance);
  var_dump($reference);
  var_dump($assigned);

结果:

代码语言:javascript
复制
 NULL
  NULL
  object(SimpleClass)#1 (1) {
    ["var"]=>
      string(30) "$assigned will have this value"
  }

这个例子我不太理解reference and value给出的

在这里,我看到了output.But的结果,我还是不明白。

我的问题是为什么$instance和$reference会变成空?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-06 17:04:00

我的问题是为什么$instance$reference会变成空?

PHP引用以一种有趣的方式运行。我要做一个真实的类比。

想象一下你有一个杯子。杯子里装满了水。

杯子是一个变量。水是变量的内容。

你创建的任何引用都指向杯子,而不是水。

如果您将杯子中的水替换为咖啡,那么所有对该杯子的引用都会突然包含相同的咖啡。

当你清空杯子的时候,所有对杯子的引用突然都是空的。

现在,对象变得非常有趣。你看,当你把它们赋值给变量时,它实际上是通过引用来实现的。但是objects by-ref不是普通的引用。在PHP交互式提示符下:

代码语言:javascript
复制
php > class Foo { public $bar; }
php > $f = new Foo();
php > $f->bar = 1;
php > $f_copy = $f;
php > $f_copy->bar = 2;
php > echo $f->bar;
2

不是你想要的,对吧?变得更有趣了。

代码语言:javascript
复制
php > $f_copy = $f;
php > $copy_ref = &$f_copy;
php > $copy_ref->bar = 3;
php > echo $f->bar;
3

这是一个更多的预期。但这是真的吗?

代码语言:javascript
复制
php > $f_copy = null;
php > print_r($copy_ref);
php > var_export($copy_ref);
NULL
php > print_r($f);
Foo Object
(
    [bar] => 3
)

正如您所看到的,即使我们完全清空了包含对对象的引用的变量,原始对象仍然保持不变,即使该对象是通过引用放入副本中的!

欢迎来到PHP,在这里这样的事情是正常的。我建议经常检查你自己的理智。

编辑:哦,还有一件事。如果需要制作对象的真实副本,则必须对其执行clone操作:

代码语言:javascript
复制
php > $not_f = clone $f;
php > $not_f->bar = 'I am not $f';
php > echo $f->bar;
3
php > echo $not_f->bar;
I am not $f

它也适用于refs:

代码语言:javascript
复制
php > $not_f_copy = $not_f;
php > $not_copy_ref = &$not_f_copy;
php > $headsplode = clone $not_copy_ref;
php > $not_f->bar = 'No, I am Spartacus!';
php > echo $headsplode->bar;
I am not $f

哦,在有人问之前:在一些语言中,引用是在值级别工作的,而不是在变量级别。Perl就是一个很好的例子。如果创建了对变量的引用,然后重新分配原始变量,则引用仍包含原始值。我是通过Perl接触PHP的,这个看似很小的差异让我非常恼火。

票数 3
EN

Stack Overflow用户

发布于 2011-04-06 16:52:08

$instance$reference都引用相同的内存位置。

如果您愿意,$instance仅仅是该内存位置的第一个名称,而$reference是第二个名称。“按引用赋值”的行为可以被描述为“通过附加名称来知道内存位置”。

如果现在将该内存位置设置为NULL,则引用该内存位置所有名称都将生成null。

但是,$assigned是原始对象的(浅)副本。因此,它位于不同的位置。这就是为什么它仍然具有$var值的原因。

PHP相关文档:

  • What References Are Not
  • Object Cloning
票数 2
EN

Stack Overflow用户

发布于 2011-04-06 16:59:11

变量的值是该变量的实际内容。例如,如果您有一个包含100个元素的字节数组,则此数组的值在内存中占用100个字节。

引用变量是不同的,它是该变量的内存地址。例如,在x86系统上,此引用应占用4个字节,而在64位系统上,此引用应占用8个字节。

以上两点说明了OOP中值和引用(指针)的常识;PHP可能以另一种不同的方式保存这些常识

$instance变为null是因为您将其设置为null,因此,对null的引用当然是null。

关于变量$assigned,当php执行这行代码时。

代码语言:javascript
复制
$assigned = $instance;

php创建另一个对象并将$instance中的值复制到$assigned,这就是为什么当您第三次调用var_dump时,它会显示$instance中的原始值,尽管在调用var_dump之前,$instance已经被设置为null。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5563658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档