zoukankan      html  css  js  c++  java
  • php对象的传递——“通过引用传递”or“传递的是object identifier”?

    摘自:http://php.net/manual/en/language.oop5.references.php

    通过上面的这段描述,我们可以知道以下几个关键点:

    1.  从php 5 开始,一个对象变了不再保存对象自己本身,而是保存的an object identifier,类比于指针。通过object identifier可以访问到实际的对象。并且在对象的参数传递、返回值、赋值中,接收这些操作的变量得到的是object identifier,而不是引用(或者说别名)。
    2. a php reference 是别名,类似于linux的软连接。

    也就是说正常情况下,对象的传递是传递的object identifier。而在加了&标志时,传递的才是引用(或者说是别名)。

    进一步理解引用和object identifier有什么区别分

    构造类如下:

     1 <?php
     2 class A{
     3     public $a;
     4     public $b;
     5     public function __construct($a,$b){
     6         $this->a=$a;
     7         $this->b=$b;
     8     }
     9     public function printContent(){
    10         echo "a=$this->a  b=$this->b
    ";
    11     }
    12 }

    进行如下操作:

     1 $aa = new A(1,2);
     2 $bb = $aa;              //传递的是object identifier
     3 $cc = &$aa;              //$cc是对象aa的别名
    4 $aa = new A(55,1); 5 echo '打印对象aa的内容'." "; 6 $aa->printContent();        //a=55  b=1 7 echo '打印对象bb的内容'." "; 8 $bb->printContent();        //a=1  b=2 9 echo '打印对象cc的内容'." "; 10 $cc->printContent();        //a=55  b=1

    由上面的输出可知,当$aa的指向的内容发生变化时,因为$cc是$aa的别名,所以跟随变化。而$bb只是保存了在执行第二行语句时和$aa相同的object identifier,在执行第四行语句后,$aa保存的object identifier变成了新的对象A(55,1)的identifier,所以$bb不受影响。

    进一步,查看参数传递过程中引用和identifier的差异:

    定义以下两个方法:

    1 function change($tmp){
    2     $tmp = new A(2,3);
    3     return $tmp;
    4 }
    5 function changeByRef(&$tmp){
    6     $tmp = new A(4,5);
    7     return $tmp;
    8 }

    执行如下操作:

     1 $aa = new A(1,2);
     2 echo '初始化时打印对象aa'."
    ";
     3 $aa->printContent();                //a=1  b=2
     4 
     5 $bb = change($aa);
     6 echo '调用change方法后打印对象aa'."
    ";
     7 $aa->printContent();                //a=1  b=2
     8 echo '调用change方法后打印返回的对象bb'."
    ";
     9 $bb->printContent();                //a=2  b=3
    10 
    11 
    12 $bb = changeByRef($aa);
    13 echo '调用changeByRef方法后打印对象aa'."
    ";
    14 $aa->printContent();                //a=4  b=5
    15 echo '调用change方法后打印返回的对象bb'."
    ";
    16 $bb->printContent();                //a=4  b=5

    可见,当传递的是object identifier时,改变方法的参数的object identifier不会影响到被传递的对象(即$aa)。而传递的是别名时则会影响到。

    需要注意的是:不论传递的是对象的object identifier或则引用,当在方法中修改对象的属性时,因为实际上修改地是相同的object,因此会影响到被传递的对象或者被引用的对象。

    更多的对象与引用的实例说明可以参考以下代码:

    摘自:http://php.net/manual/en/language.oop5.references.php

    <?php
    class Foo {
      private static $used;
      private $id;
      public function __construct() {
        $id = $used++;
      }
      public function __clone() {
        $id = $used++;
      }
    }
    
    $a = new Foo; // $a is a pointer pointing to Foo object 0
    $b = $a; // $b is a pointer pointing to Foo object 0, however, $b is a copy of $a
    $c = &$a; // $c and $a are now references of a pointer pointing to Foo object 0
    $a = new Foo; // $a and $c are now references of a pointer pointing to Foo object 1, $b is still a pointer pointing to Foo object 0
    unset($a); // A reference with reference count 1 is automatically converted back to a value. Now $c is a pointer to Foo object 1
    $a = &$b; // $a and $b are now references of a pointer pointing to Foo object 0
    $a = NULL; // $a and $b now become a reference to NULL. Foo object 0 can be garbage collected now
    unset($b); // $b no longer exists and $a is now NULL
    $a = clone $c; // $a is now a pointer to Foo object 2, $c remains a pointer to Foo object 1
    unset($c); // Foo object 1 can be garbage collected now.
    $c = $a; // $c and $a are pointers pointing to Foo object 2
    unset($a); // Foo object 2 is still pointed by $c
    $a = &$c; // Foo object 2 has 1 pointers pointing to it only, that pointer has 2 references: $a and $c;
    const ABC = TRUE;
    if(ABC) {
      $a = NULL; // Foo object 2 can be garbage collected now because $a and $c are now a reference to the same NULL value
    } else {
      unset($a); // Foo object 2 is still pointed to $c
    }

     

  • 相关阅读:
    python 之 Multiprocessing 多进程
    python 之 Threading 多线程
    Python实战 -- 利用Flask搭建微电影网站(一)蓝图构建
    R语言学习——作图
    python 之 pandas 总结
    python 之 numpy 总结
    C++使用Jsoncpp源码
    C++左值、左值引用、右值、右值引用
    std::forward
    std::move
  • 原文地址:https://www.cnblogs.com/jade640/p/6623105.html
Copyright © 2011-2022 走看看