2007年06月27日

Stack - Example for Operators of Array Overload

Tags: php spl iterator overloading

實作一個 Stack 。具備下列特性:

  1. 後進先出。
  2. 順序走訪時,同樣按後進先出原則走訪。亦即由後往前走訪。
  3. 可用索引運算子[]窺探 Stack 的內容。
  4. 不允許用索引運算子改變 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
樂多分類:網路/3C 共同主題:PHP基本語法 工具:編輯本文
Ads by Roodo! 

引用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');
}
Posted by racklin at 2007年06月29日 10:13
喔,那不是 memory leak,而是我的設計。

其實按 PHP 的陣列用法,我大可不指定 size ,反正可以隨時增加或縮減。但我給了 size ,我的意思就是要一個固定大小的 stack。隱含的效率意義是: 我就是要這麼大的stack放在那裡,系統不用管理這塊記憶體。
Posted by 遊手好閒的石頭成 at 2007年06月29日 12:07
更正。剛剛回應太快,以為是指陣列大小的事。

我剛瞄了一下 pop() ,發現我還真的漏掉 unset 了。我明明記得我有寫...
嗯,一定是我在改的時候,不小心改錯了 (遠目

ps.回傳 reference 比較快,免得 copy object 兩次。
$r = $table[$sp] // copy 1
return $r // copy 2
Posted by 遊手好閒的石頭成 at 2007年06月29日 15:44