Клон SplHeap, который содержит объекты в PHP
Я хотел бы знать, как я могу клонировать расширенный класс SplHeap, который содержит объекты. Например, если FooHeap расширяет SplHeap, возможно ли для FooHeap иметь метод __clone и клонировать его элементы объекта?
class FooHeap extends SplHeap{
public function compare($value1, $value2){.... }
public function __clone(){
// how do I access its elements to clone?
}
}
В качестве альтернативы, если мне нужно создать новый объект FooHeap и повторно вставить клоны элементов объекта, есть ли способ (например, сверху вниз или снизу вверх), что мне следует повторно вставить клонированные элементы, чтобы оптимизированная производительность?
2 ответа
Суть SplHeap заключается в том, что он автоматически сортирует все вставленные значения (например, объекты), и при итерации по нему каждое значение удаляется из кучи.
Когда вы клонируете кучу, вставленные значения также копируются, но объекты не клонируются, а копируются как ссылки, как и ожидалось.
Обычный подход состоит в том, чтобы перебрать сохраненные данные и клонировать каждый найденный объект. Но поскольку итерация удаляет узлы, вы должны где-то собрать их и вставить заново.
Там нет выбора в порядке, потому что все, что вы можете сделать, это "получить следующий".
Если вы беспокоитесь о производительности, измерьте!
Я обнаружил, что этот код работает:
class MyHeap extends SplHeap
{
public function compare($a, $b)
{
return (strcmp(get_class($a), get_class($b)));
}
public function __clone()
{
echo "Im cloning in ";
foreach ($this as $obj) {
$clones[] = clone($obj);
}
foreach ($clones as $obj) {
$this->insert($obj);
}
var_dump($this);
}
}
$heap = new MyHeap();
$obj1 = new stdClass();
$heap->insert($obj1);
$obj2 = new stdClass();
$heap->insert($obj2);
var_dump($heap);
$clone = clone($heap);
var_dump($clone);
foreach ($clone as $insert) {
var_dump($insert);
}
foreach ($heap as $insert) {
var_dump($insert);
}
Выходы:
class MyHeap#1 (0) {
}
Im cloning in class MyHeap#4 (0) {
}
class MyHeap#4 (0) {
}
class stdClass#6 (0) {
}
class stdClass#7 (0) {
}
class stdClass#2 (0) {
}
class stdClass#3 (0) {
}
Определив функцию __clone, вы можете указать, какие переменные вы хотите изменить для клонированного объекта. В следующем примере я установил $cloned в true. Оригинальный объект имеет $clone = false
, но клонированный имеет $cloned = true
, Поэтому $data остается неизменным.
<?php
class FooHeap extends SplHeap {
public $data = "asd" ;
private $cloned = false ;
public function __clone(){
$this->cloned = true ;
$this->rewind() ; //Just rewind iterator back to start, if you need
}
public function compare(){
}
}
$original = new FooHeap() ;
$original->insert("some stuff") ;
$original->insert(100) ;
$clone = clone $original ; //Data nodes are cloned from original object
$data = array() ;
$length = $clone->count() ;
for ($i = 0 ; $i < $length ; $i++){
$data[] = $clone->current() ; //Access current data node and store it in data
$clone->next() ; // Move to the next data node
}
var_dump($data) ; //Check your data array
?>