【发布时间】:2011-12-11 07:50:34
【问题描述】:
在 PHP 中,如果你创建一个对象数组,对象方法(不是数据成员)是为数组中的每个对象实例复制的,还是只复制一次?我会假设出于记忆的原因,后者是正确的;我只是想向 StackOverflow 社区确认这是真的。
例如,假设我有一个带有几个方法的类 MyClass,即
class MyClass {
public $data1;
private $data2;
public function MyClass($d1, $d2) {
$this->data1=$d1; $this->data2=$d2;
}
public function method1() { }
public function method2() { }
}
显然,实际上method1() 和method2() 不是空函数。 现在假设我创建了一个由这些对象组成的数组:
$arr = array();
$arr[0] = & new MyClass(1,2);
$arr[1] = & new MyClass(3,4);
$arr[2] = & new MyClass(5,6);
因此,PHP 为三个对象实例中的每一个在内存中存储了三组数据成员。我的问题是,PHP 是否还为 $arr 的 3 个元素中的每一个存储了 3 次 method1() 和 method2()(以及构造函数)的副本?我正在尝试确定一个包含约 200 个对象的数组是否会过于占用内存,因为必须在内存中存储每个方法的 200 个副本。
感谢您的宝贵时间。
【问题讨论】:
-
根据定义,方法肯定是对过程的引用?在这种情况下,过程的机制将只定义一次(当你加载类时,not 当你实例化一个对象时)并且所有实例都将简单地指向该过程。这纯粹是猜测,但我看不出它是任何类型的方法/函数的任何其他方式,除非它是一个闭包。
-
嗯。好问题。想知道在这些方法中定义的任何静态变量会发生什么。它是由方法的每个实例共享的一个静态变量,还是每个实例都有自己唯一的静态变量。
-
@DaveRandom 在 Javascript 中,当您定义一个类时,方法会嵌入到对象中。它们的内容不会在实例之间“共享”。
-
@Matthieu 同意,但是 Javascript 是一个完全不同的球类游戏,因为 JS 中的或多或少的 everything 本身就是一个对象——包括方法。但同样取决于您如何定义方法 - 如果您这样做
String.prototype.methodName = function () {};每个字符串对象都有一个名为methodName的方法,但它们并不都有自己的过程副本,它们将调用属于 @987654325 的方法@。在您执行mystr.methodName = function () {};并覆盖该方法之前,mystr拥有它自己的副本。但是对于 PHP(我相信)我的说法是正确的。