Re: [問題] 多型的自動回收

看板C_and_CPP (C/C++)作者 (水無月真夜)時間16年前 (2009/10/08 03:04), 編輯推噓1(103)
留言4則, 1人參與, 最新討論串10/13 (看更多)
※ 引述《yoco315 (眠月)》之銘言: : 不要 = =" : 既然資源是在 D 配的,D 要自己處理,不要給 B 管 : 所以這邊改成這樣 : virtual ~Base() {} // 蝦米都不做 : : class Derived { : : virtual void doClose() { : : // ... : : } : 然後 D 加上解構子 : virtual ~Derived () { // 我自己來 XD : D::doClose(); // ~B() 不能呼叫虛擬函數 : } // 我自己呼叫應該沒問題吧??? : 還是我哪邊錯惹?????????? 如果我的理解沒錯 原po他希望的是 Derived裡面有個function負責relase資源 但是在錯誤使用(delete 前忘了呼叫close的時侯)能夠自動釋放 而且重要的是,希望能在Derived的設計者「忘了」在dtor呼叫doClose的時侯 只要是從Base class繼承出來的class都能自動的去呼叫doClose 後面這就是重點了 因為Base和Derived的設計者有可能是不同人 可能document沒寫清楚 又或者單純忘記了 總之因為種種原因 原po希望能在Base class裡就自動的有機制去處理這件事.. 所以現在的問題是:唯一在物件銷毀時會自動執行的只有dtor 但是dtor中又不能呼叫virtual function 解決方法也就很直觀了..那就是寫成兩個class 也就是把介面和實作分開來就好了 就像#1Ap2yPNw提到的那樣 剛好有個design pattern叫作bridge.. 這有兩種寫法 動態多型的寫法就像前述文章那樣 class Base { BaseImpl* pImpl; public: void open() { pImpl->doOpen(); } void close() { pImpl->doClose(); } void someOperation() { pImpl->someOperation(); } ~Base() { content->doClose(); delete pImpl; } } class BaseImpl { friend Base; virtual void doOpen()= 0; virtual void doClose()= 0; void someOperation() {}; } 如此這般 Base只提供一個操作的介面 實際的動作是委託給BaseImpl進行的 這樣Derived class只要繼承BaseImpl 自然就能成為一個Base的實作體 靜態多型的寫法是像下面這樣 template <typename T> class BaseInterface { T impl; public: void open() { impl._open(); } void close() { impl._close(); } void someOperation() { impl._someOperation(); } ~BaseImpl() { impl._close(); } } class DerviedImpl { //implematation here }; typdef BaseInterface<DerivedImpl> Derived; 靜態多型的方法可以省掉virtual function的呼叫成本 當然缺點就是沒辦法在run-time改變型別 不過如果以原po的需求:管理資源open和close的class集來說 應該不會要用動態多型..所以後者是比較建議的方法 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.13.219 ※ 編輯: minazukimaya 來自: 114.32.13.219 (10/08 03:06)

10/08 12:17, , 1F
沒錯,我完全就是這個意思 XD
10/08 12:17, 1F

10/08 12:18, , 2F
不過我的確需要用到動態多型,因為 subclasses 的部分
10/08 12:18, 2F

10/08 12:18, , 3F
是用 plugins 的方式 dynamic load 進來
10/08 12:18, 3F

10/08 12:19, , 4F
看來必須要考慮是否值得為了這個舉動增加class的複雜度
10/08 12:19, 4F
文章代碼(AID): #1ApEOhjS (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1ApEOhjS (C_and_CPP)