我有一个包含width / height属性的简单'dimension'类和一个用于设置它们的构造函数。
我有一个函数(重新调整尺寸),它采用两个维度对象 - 一个要重新调整大小,另一个包含最大大小。它应该减小第一个参数中的尺寸,使它们“适合”第二个参数。
然后它返回第一个新调整大小的文件。
调用者传递维度对象并将返回值转换为另一个 - 因为它必须保留原始对象。但传递给函数的那个会被修改。
这是令人惊讶的,因为我没有参考它:
private function scale_image_dimensions(Dimensions $dimensions, Dimensions $max_size) {
if( $dimensions->width > $max_size->width ) {
$dimensions->height = $dimensions->height / ($dimensions->width / $max_size->width);
$dimensions->width = $max_size->width;
}
if( $dimensions->height > $max_size->height ) {
$dimensions->width = $dimensions->width / ($dimensions->height / $max_size->height);
$dimensions->height = $max_size->height;
}
return $dimensions;
}
如何指定我希望函数复制传递给它的对象,然后返回其中一个?
似乎其他东西是可疑的 - 我将论点从$dimensions
更改为$adimensions
,并将$dimensions = $adimensions
放在函数的开头。
但调用者的变量仍然被修改了!作业也可以参考吗?我的意思是......没有办法使赋值运算符重载,或者复制构造函数如此......我该怎么办?如果我想要一个副本,我必须每次显式初始化一个?
答案 0 :(得分:3)
编辑:对象通过引用分配并通过引用传递。
如果需要深层克隆对象,请使用$cloned = clone $dimensions
中的clone关键字,并在__clone()
类中定义魔术方法Dimensions
,以确保任何对象引用内部Dimensions
实际上也是克隆的。
答案 1 :(得分:2)
默认情况下,所有对象都称为引用。要创建对象的副本,必须使用clone关键字克隆它。
private function scale_image_dimensions(Dimensions $dimensions, Dimensions $max_size) {
$old_dimensions = $dimensions;
$dimensions = clone $dimensions;
if( $dimensions->width > $max_size->width ) {
$dimensions->height = $dimensions->height / ($dimensions->width / $max_size->width);
$dimensions->width = $max_size->width;
}
if( $dimensions->height > $max_size->height ) {
$dimensions->width = $dimensions->width / ($dimensions->height / $max_size->height);
$dimensions->height = $max_size->height;
}
return $dimensions;
}
这使得PHP不会产生大量对象,并且通常人们希望通过引用传递对象。
PHP类通常不会用作“数据存储”实用程序,因为数组通常也可以正常工作。
但是,如果您要使用另一种使用许多类来存储数据的语言,我可以看到这将是一个大问题。
答案 2 :(得分:1)
可能the clone keyword可能正是您要找的吗?
$return_dimensions = clone $dimensions;
答案 3 :(得分:1)
PHP5自动将params作为引用处理。您可以使用clone关键字克隆该对象。
$newObject = clone $originalObject;
您应该关注的一件事是克隆时完整拷贝和浅拷贝之间的区别。默认情况下,clone只会生成浅拷贝。
答案 4 :(得分:1)
在某种意义上,参数是按值传递的,因为您可以重新分配$维度而不会影响原始维度。
但是对象变量只是指向实际对象的指针,所以改变它们的成员变量会影响原始对象是正确的。
如果要避免这种情况,则需要克隆对象。 PHP具有cloning功能,但请记住,默认情况下它会生成浅拷贝。因此,如果您的对象包含其他对象,您将无法获得这些对象的克隆;只是对原件的引用。您可能只想手动创建新对象并自行复制它们的值。