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

看板C_and_CPP (C/C++)作者 (沒事多聊天~ 歡迎打屁)時間16年前 (2009/10/08 04:44), 編輯推噓2(207)
留言9則, 3人參與, 最新討論串11/13 (看更多)
※ 引述《minazukimaya (水無月真夜)》之銘言: : ※ 引述《yoco315 (眠月)》之銘言: : : 不要 = =" : : 既然資源是在 D 配的,D 要自己處理,不要給 B 管 : : 所以這邊改成這樣 : : virtual ~Base() {} // 蝦米都不做 : : 然後 D 加上解構子 : : virtual ~Derived () { // 我自己來 XD : : D::doClose(); // ~B() 不能呼叫虛擬函數 : : } // 我自己呼叫應該沒問題吧??? : : 還是我哪邊錯惹?????????? : 如果我的理解沒錯 : 原po他希望的是 Derived裡面有個function負責relase資源 : 但是在錯誤使用(delete 前忘了呼叫close的時侯)能夠自動釋放 : 而且重要的是,希望能在Derived的設計者「忘了」在dtor呼叫doClose的時侯 : 只要是從Base class繼承出來的class都能自動的去呼叫doClose 我覺得這發生的機會比較少,如果會去改寫doClose的話, 應該不會忘了在dtor裡面加上自動呼叫。 我覺得原PO不是為了這個問題,而是原PO使用template method pattern, 想呼叫的是 close() 不是 doClose()。 // template method close() { ...... //some statements doClose(); //some statements SomeMoreVFunc(); //some statements ..... } 如果真的"只是"要確保doClose()呼叫動作被叫到,那直接在dtor內呼叫 doClose() 的 特定實作版本就好了吧? 而且也應該不用擔心重複呼叫的問題,doClose()內應該有機制 要避免這件事情,且各自class的doClose應該只負責釋放自己的額外產生的資源。 virtual ~Base(){ Base::doClose(); } virtual ~Derived(){ Derived::doClose(); } virtual ~Derived2(){ } //沒改寫實作就不用特別呼叫 : 後面這就是重點了 因為Base和Derived的設計者有可能是不同人 : 可能document沒寫清楚 又或者單純忘記了 總之因為種種原因 : 原po希望能在Base class裡就自動的有機制去處理這件事.. 也許真的是這樣,但如果是這樣,我到覺得不必為了避免錯誤的使用方法 而改變class的設計。因為我覺得會去改寫/繼承這些與資源釋放相關class的使用者 都應該是進階使用者。只有單純使用class的使用者才比較初階。 不過也許原PO真的這麼貼心也說不定 XD : 所以現在的問題是:唯一在物件銷毀時會自動執行的只有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的實作體 只是比較醜一點 XD Base b(new DerivedImpl()); shared_ptr ptr(new Base(new DerivedImpl())); : 靜態多型的寫法是像下面這樣 : 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集來說 : 應該不會要用動態多型..所以後者是比較建議的方法 我覺得多型在這種情形也用得很多耶 例如常見的 stream 就有很多種,需要資源管理也需要多型處理 :P -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.124.96.179

10/08 09:35, , 1F
靜態多型也是多型啊..主要的問題在於有沒有動態綁定
10/08 09:35, 1F

10/08 09:35, , 2F
的需求吧..
10/08 09:35, 2F

10/08 09:35, , 3F
動態多型最重要的好處是可以用一個container就處理
10/08 09:35, 3F

10/08 09:35, , 4F
heterogeneous collection..
10/08 09:35, 4F

10/08 09:40, , 5F
C++ templates: the complete guide第14.3節有討論這
10/08 09:40, 5F

10/08 09:40, , 6F
兩者分別適用在哪些地方
10/08 09:40, 6F

10/08 10:42, , 7F
sure @@ 我最後指的是deliver一個bin library之類的情況
10/08 10:42, 7F

10/08 10:43, , 8F
好幾篇之前我也有回別人靜態多型是利用甚麼...
10/08 10:43, 8F

10/08 12:20, , 9F
sorry, 我就是這麼貼心 orz
10/08 12:20, 9F
文章代碼(AID): #1ApFstFa (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1ApFstFa (C_and_CPP)