看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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)
legnaleurc:沒錯,我完全就是這個意思 XD 10/08 12:17
legnaleurc:不過我的確需要用到動態多型,因為 subclasses 的部分 10/08 12:18
legnaleurc:是用 plugins 的方式 dynamic load 進來 10/08 12:18
legnaleurc:看來必須要考慮是否值得為了這個舉動增加class的複雜度 10/08 12:19