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) {
}
這聽起來像你想堆的深層副本(參見淺拷貝,其中堆積對象每個堆中都是一樣的)。是對的嗎? – salathe 2013-02-16 10:38:10
是的,我想要一個堆的深層副本。有什麼辦法可以解決這個問題嗎? – Wee 2013-02-16 10:42:37
我可能只是遍歷堆(在'__clone()'內部),臨時存儲克隆對象的某處('SplObjectStorage','SplFixedArray'等)。一旦完成第一個循環,堆將是空的,此時您可以遍歷臨時存儲和'insert()'克隆的對象。 – salathe 2013-02-16 11:06:41