__clone() implementation
| From: | Stephane Drouard | Date: | Thu, 22 Jan 2004 14:37:11 +0000 |
| Subject: | __clone() implementation | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-7270@lists.php.net to get a copy of this message | ||
I'm currently using PHP4 and I'm evaluating PHP5 for its new exciting features.
I have some remarks, split into distinct posts.
The first one is about the current implementation of __clone():
* a derived __clone() can't call parent::__clone() because $that is only declared for the first
__clone() call. So a derived __clone() has to include the code of its parent's __clone().
It's not only bad programming, but it can't work when a parent implements private members.
* when a class implements __clone(), all its derived classes have also to implement it to transfer
their own members.
There are a several possibilities to get round the first point, but in order to also simplify
__clone() implementation, here is a way it could be implemented, close to __construct()
implementation:
* the system firstly does a bit for bit copy of the source object,
* then it calls __clone() (which at worst does nothing, if no class implements it),
* __clone() accesses members using $this to handle those (and only those) that need particular
actions,
* this is the responsibility of a derived __clone() to call (or not) parent::__clone().
Advantages:
* same behaviour as __construct(), except that $this is already initialized,
* it guaranties that all members will be transfered, by reference for objects, by copy for the
others,
* __clone() just needs to be implemented to handle members that need particular actions,
* derived classes do not need to implement __clone() when one of its parents does,
* no more need of $that.
In terms of performance, I don't think this implementation is bad, because a bit for bit copy
is certainly faster than an interpreted member-to-member transfer, except if all members have to be
handled in a particular way.
I also consider the __clone() implementation not coherent with its calling syntax.
Indeed "$newObj = $obj->__clone();" lets think of an implementation like this:
<?
class Foo {
function __clone() {
$o = new Foo($this->..., $this->...);
$o->...; // eventually
return $o;
}
}
?>
Because __clone() is considered as a copy constructor, it could be implemented in a similar way as
for object construction, for example: "$newObj = clone $obj;", "clone" being a
language keyword.
Regards,
Stephane