Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
克隆包含PHP中对象的SplHeap_Php_Clone_Spl - Fatal编程技术网

克隆包含PHP中对象的SplHeap

克隆包含PHP中对象的SplHeap,php,clone,spl,Php,Clone,Spl,我想知道如何克隆包含对象的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?

我想知道如何克隆包含对象的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对象并重新插入对象元素的克隆,有没有办法(例如从上到下或从下到上)我是否应该重新插入克隆的元素以确保优化的性能?

通过定义函数克隆,您可以指定要为克隆对象更改哪些变量。在下一个示例中,我将$Clone设置为true。原始对象具有
$clone=false
,但克隆的对象具有
$clone=true
。因此,美元数据保持不变

<?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

?>

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);
}
产出:

classmyheap#1(0){
}
在类MyHeap#4(0)中克隆Im{
}
类MyHeap#4(0){
}
等级标准等级6(0){
}
等级标准等级7(0){
}
等级标准等级2(0){
}
等级标准等级3(0){
}

但是如何访问存储在SplHeap中的数据节点?听起来您需要一个堆的深度副本(参见浅层副本,其中每个堆中的堆对象都是一个相同的对象)。是吗?是的,我想要一个堆的深度副本。有什么方法可以实现吗?我可能只是在堆上循环(在
\uu clone()
内),将克隆对象临时存储在某个地方(
SplObjectStorage
SplFixedArray
等)。第一个循环完成后,堆将为空,此时您可以在临时存储区和克隆对象上循环。