1

オブジェクトを含む 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 オブジェクトを作成し、オブジェクト要素のクローンを再挿入する必要がある場合、確実にクローン要素を再挿入する方法 (たとえば、上から下、または下から上) はありますか?最適化されたパフォーマンス?

4

2 に答える 2

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) {
}
于 2013-02-16T11:13:51.093 に答える
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

?>
于 2013-02-16T09:52:10.820 に答える