Stack - Example for Operators of Array Overload
Tags: php spl iterator overloading
實作一個 Stack 。具備下列特性:
- 後進先出。
- 順序走訪時,同樣按後進先出原則走訪。亦即由後往前走訪。
- 可用索引運算子
[]窺探 Stack 的內容。
- 不允許用索引運算子改變 Stack 的內容。
本文之示範直接實作 Iterator, ArrayAccess, Countable 三個介面,而不繼承 ArrayIterator 等類別。ArrayIterator 類具有 sort() 等方法,但我並不打算對 Stack 進行排序,故我不繼承。若我繼承 ArrayIterator ,則我必須覆寫 sort 等方法,無此必要。
Stack.php
Example:
StackTest.php
Posted by shirock at
樂多Roodo! │10:41
│
回應(3)
│
引用(0)
│
PHP
引用URL
http://cgi.blog.roodo.com/trackback/3542135
呵~專案剛結案, 比較閒來和您以文會友~
您這個 Stack 範例存在有 memory leak 的問題.
而 Stack 範例剛好又在 Effective Java Programming Language Guide (Item 5: Eliminate obsolete object references) 有提到且很常發生.
在 PHP 其實問題不會很嚴重, 因為 PHP 目前並沒有 Application Server, 也就是物件不會被永續存在, 在每一次的 request 結束後, 問題也就消失了.
不過還是來探討一下:
如果這個 Stack 成長後縮小, 也就是假設 push 到 5 個, 而 pop 出 2 個, $this->table 依然還是暫有 5 個的記憶體, 因為被 popped off 的物件不會被回收, 即使它也將不會再被引用到
改成即可解決此問題:
public function pop() {
if ($this->sp > 0)
$result = $this->table[--$this->sp];
unset($this->table[$this->sp]);
return $result;
else
throw new Exception('stack is empty');
}
喔,那不是 memory leak,而是我的設計。
其實按 PHP 的陣列用法,我大可不指定 size ,反正可以隨時增加或縮減。但我給了 size ,我的意思就是要一個固定大小的 stack。隱含的效率意義是: 我就是要這麼大的stack放在那裡,系統不用管理這塊記憶體。
更正。剛剛回應太快,以為是指陣列大小的事。
我剛瞄了一下 pop() ,發現我還真的漏掉 unset 了。我明明記得我有寫...
嗯,一定是我在改的時候,不小心改錯了 (遠目
ps.回傳 reference 比較快,免得 copy object 兩次。
$r = $table[$sp] // copy 1
return $r // copy 2