What have you found for these years?

2008-01-06

enable_shared_from_this (2)

我忽然想到這樣實作 enable_shared_from_this 的問題是什麼了。
凡暴力法必有其 drawback...

因為 enable_shared_form_this 暴力地在其 member 中塞入
internal weak_ptr, 這也表示 this 和 share_ptr 變成相依性非常高。
於是,這限制了一個 instance 只能被一族的 shared_ptr 所 share.

應該畫個圖才對... 不過我懶。總之,可以想像一族的 shared_ptr 就是
一個 instance 被一群共有一個 deleter 的 shared_ptr 共有。而這一族
當然也會有一組 reference counting. 當其 counting 降至零,則喚起 deleter.

只要你用了 enable_shared_from_this, 則只能有這樣一族的 shared_ptr.
什麼時候需要用到第二族?當你把 resource 再往上拉一個層級時,
這種作法就有可能用到了。例如假設你有一個生物,他被另一群生物共有。
假設這一群擁有者死去,則這個生物的 HP 會減少 100.

假設這個生物可以被超過一群的擁有者擁有?比方說,綠色生物擁有他,
紅色生物也擁有他。當綠色生物死光時,HP -100, 當紅色生物死光時,
HP -200. 這可以用 share_ptr 去 model... 讓這個 instance 被兩組
擁有不同 deleter(一個是 HP-100, 一個是 HP-200)的 shared_ptr 擁有。

可是 enable_shared_from_this 是假設只會有一組的 shared_ptr,
超過兩組就會發生打架的狀況了,因為 internal weak_ptr 會被改來改去...
這樣肯定會死掉的。也就是說,當你需要兩組以上的 shared_ptr,
就完全不能使用 enable_shared_form_this.

不過其實這個想法就又跟我原本的想法不同了。我原本是假設一個 instance
必然只會有一個 shared_ptr 族群,所以以下的操作應該要是 valid:

A* a = new A;
shared_ptr<A> sa1(a);
shared_ptr<A> sa2(a);

但事實上現有的實作上,這必然會產生 double delete...
因為這樣其實就已經是兩個不同體系的 shared_ptr.

所以我想 shared_ptr 也許可以再拆成三種實作,第一種當然就是原本的。
第二種則是內部有個 map, 他可以知道每一個 instance 被哪個 shared_ptr 擁有,
進而使得上面的 code 是 valid, 不會 double delete.

第三種,就是我最上面所說的,可以有多個 shared_ptr 族群,
使得你可以用更 general 的方式去看 recourse 是什麼東西?

說到這個,之前在 OOAD 有個不是很愉快的討論經驗。
所以我想以後也許不會再特別到討論板發心得了吧...
這幾篇本來是有點想貼到 ptt 上的,正好那時 ptt 連不上,
現在想想就算了,我自言自語就好了。

這篇沒解釋到 enable_shared_from_this, 下篇待續。
建議閱讀順序就會是 1 3 2 了...

btw, smart pointer 果然是個很好的研究課題...
做得好的話,可是會比一般的 gc 要來得強大許多 :D

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0