用"new"实例化时到底发生了什么? [英] What is exactly happening when instantiating with 'new'?

查看:98
本文介绍了用"new"实例化时到底发生了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们考虑以下代码:

class a {
    public $var1;
    function disp(){
        echo $this->var1;
        }    
    }

$obj1 = new a;
echo '<br/>After instantiation into $obj1:<br/>';    
xdebug_debug_zval('obj1');  

$obj1->var1 = "Hello ";
echo '<br/><br/>After assigning "Hello" to  $obj->var1:<br/>';
$obj1->disp();

echo "<br/><br/>";  
xdebug_debug_zval('obj1');  

输出:

实例化为$ obj1之后:
obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 2,is_ref = 0)= NULL}

为$ obj-> var1分配"Hello"后:
你好

obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 1,is_ref = 0)='Hello'}

一个接一个:

实例化为$ obj1之后:
obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 2,is_ref = 0)= NULL}

当只有一个类a的对象时,为什么$obj1->var1具有refcount=2?

是因为new运算符如何进行赋值? PHP用引用进行赋值.用new实例化时,没有符号/变量名称与该实例相关联.但是,类属性确实具有名称. recount=2是因为这个原因吗?

如果是这种情况,则发生了C.O.W(写时复制),并带有类实例的浅副本WRT.这些属性仍指向使用new实例化期间创建的属性的zval.

现在

为$ obj-> var1分配"Hello"后:
你好

obj1:(refcount = 1,is_ref = 0)= class a {public $ var1 =(refcount = 1,is_ref = 0)='Hello'}

因此,当我为属性$obj1->var1分配一个值时,该属性将使用一个新的zval容器,并因此为refcount=1?

这是否意味着在实例化期间使用new创建的zval容器仍然存在,但是由于没有符号/变量名与之关联而无法访问?

请注意(摘自 xdebug:可变显示功能):
debug_zval_dump()xdebug_debug_zval()不同.

无效 xdebug_debug_zval( [string varname [,...]] )

显示有关变量的信息.

此函数显示有关一个或多个变量的结构化信息,包括其类型,值和引用计数信息.使用值递归探究数组.此功能的实现不同于PHP的 debug_zval_dump()函数,以便解决该函数的问题之所以这样,是因为变量本身实际上已传递给函数. Xdebug的版本更好,因为它使用变量名称在内部符号表中查找变量并直接访问所有属性,而不必处理实际将变量传递给函数的情况.结果是,此函数返回的信息比PHP自身的用于显示zval信息的函数准确得多.

UPDATE :Dec 31th 2011:

我正在尝试查看使用 new 时如何进行内存分配.但是,我现在还有很多其他事情要做.我希望我能够尽快发布有用的更新. 在此之前,这里是我正在查看的代码的链接:

解决方案

添加另一个实例化$obj2 = new a;将refcount增加到3,而不是4,因此,这是由于调用xdebug_debug_zval而发生的. xdebug函数的目的是避免将变量传递给函数并(可能)创建额外的引用而造成的混乱.

不幸的是,这不适用于成员变量.将为这些zval创建另一个引用以将其导出.因此, debug_zval_dump文档的注释中列出的所有警告和令人困惑的情况仍然适用于成员变量. >

Let's consider the following code:

class a {
    public $var1;
    function disp(){
        echo $this->var1;
        }    
    }

$obj1 = new a;
echo '<br/>After instantiation into $obj1:<br/>';    
xdebug_debug_zval('obj1');  

$obj1->var1 = "Hello ";
echo '<br/><br/>After assigning "Hello" to  $obj->var1:<br/>';
$obj1->disp();

echo "<br/><br/>";  
xdebug_debug_zval('obj1');  

The output:

After instantiation into $obj1:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }

After assigning "Hello" to $obj->var1:
Hello

obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }

One by one:

After instantiation into $obj1:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }

Why does $obj1->var1 have refcount=2 when there is only one object of class a?

Is it because of how the new operator makes assignment? PHP does assignment with references. When instantiated with new, no symbol/variable name is associated with that instance. But, the class properties do have names. Is the recount=2 because of this?

If that is the case then a C.O.W (copy on write) has occurred with a shallow copy WRT the class instance. While the properties are still pointing to the zval's of properties created during the instantiation using new.

Now,

After assigning "Hello" to $obj->var1:
Hello

obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }

So, when I assign a value to the property $obj1->var1 a new zval container for that property and hence the refcount=1?

Does this mean that the zval container created during instantiation using new still lives but cannot be accessed since there is no symbol / variable name associated with it?

Please note (from xdebug: Variable Display Features):
debug_zval_dump() is different from xdebug_debug_zval().

void xdebug_debug_zval( [string varname [, ...]] )

Displays information about a variable.

This function displays structured information about one or more variables that includes its type, value and refcount information. Arrays are explored recursively with values. This function is implemented differently from PHP's debug_zval_dump() function in order to work around the problems that that function has because the variable itself is actually passed to the function. Xdebug's version is better as it uses the variable name to lookup the variable in the internal symbol table and accesses all the properties directly without having to deal with actually passing a variable to a function. The result is that the information that this function returns is much more accurate than PHP's own function for showing zval information.

UPDATE : Dec 31th 2011:

I am trying to look at how memory allocation takes place when new is used. But There are too many other things I have to do right now. I hope I will be able to post an useful update soon. Until then here are the links to code at which I was looking at :

解决方案

Adding another instantiation $obj2 = new a; increases the refcount to 3, not 4, so it's something which happens as a result of calling xdebug_debug_zval. The purpose of the xdebug function is to avoid the confusion from the passing the variable into the function and (possibly) creating an extra reference.

Unfortunately, this does not apply to the member variables; another reference is created to those zvals in order to export them. Therefore, all the caveats and confusing circumstances listed in the note on the debug_zval_dump documentation still apply for the member variables.

这篇关于用"new"实例化时到底发生了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆