[問題] link list 由不同資料型態串起來

看板C_and_CPP作者 (☆㊣↖煞氣ㄟ阿喂↘ξ★)時間15年前 (2010/03/05 00:45), 編輯推噓3(3010)
留言13則, 5人參與, 最新討論串1/2 (看更多)
我最近一直在想這個問題,而且想用C++來完成,來練習泛型。 如果有一個LIST想串起很多不同型態的資料,所以我定義一個struct: enum TYPE{ .... }; struct EVENT{ void* dataPtr; EVENT* link; TYPE type; }; class LIST{ private: int count; EVENT* pos; EVENT* head; EVENT* rear; int (*compare) (void* argu1, void* argu2); public: LIST( int (*compare) (void* argu1, void* argu2) ); ~LIST(); ......... // 尚有 Insert(.), Search(.), 等...// }; LIST::~LIST(){ //// Local definition //// EVENT* deletePtr; //// Statement //// while(count > 0){ //// First delete data //// delete head->datPtr; /// 這行有疑問!! /// //// Delete event //// deletePtr = head; head = head->link; count--; delete deletePtr; }// while count>0 } 觀念上很簡單,就是destructor會先把list中第一個Event的data釋放掉, 然後再釋放Event本身,依此類推。 感覺很良好~ ============ 現在,我的問題出現了, 如果我Event的void* 指向的是另一種結構體, EX: struct A{ int x; int* ptr; ~A(){ if( ptr != NULL ) delete ptr; }; } struct B{ double x; int y; double* ptr1; int* ptr2; ~B(){ if( ptr1 != NULL ) delete ptr1; if( ptr2 != NULL ) delete ptr1; }; } 那這樣問題就麻煩了,List的destructor必須要知道目前將delete的Event, 其指向的data是結構A還是B,然後根據Event的TYPE欄位的指示來轉型, 不然A或B的destructor就會呼叫不到。這樣子很不實際也很麻煩吧? 應該沒有人願意在List的destructor內寫一個switch-case弄完轉型,再delete吧? 況且程式一大,很容易出錯...... =========== 所以,我想說那不然把Event的結構做成樣板好了: template< typename T > struct EVENT{ T* dataPtr; EVENT* link; TYPE type; }; template< typename T > class LIST{ private: int count; EVENT<T>* pos; EVENT<T>* head; EVENT<T>* rear; int (*compare) (void* argu1, void* argu2); public: LIST( int (*compare) (void* argu1, void* argu2) ); ~LIST(); ......... // 尚有 Insert(.), Search(.), 等...// }; 可是這樣看起來,好像是一個樣板可以做出任意型態的Event, 但是一旦List宣告成某一型態T, 好像這個List就是只能吃固定的型態了..... 似乎跟我想的目標不一樣,像是在main裡宣告LIST list<A> 這個List串起來的Event就是只吃A型態的data,這不是我想要的... 想跟各位板友討論看看, 因為我最近在練習C++,就用C++來完成吧! 看是要用繼承、泛型等。 希望各位指點一下! 謝謝大家! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.230.181.215

03/05 00:51, , 1F
google "virtual destructor"
03/05 00:51, 1F
我有找了一下,不過就我知道的,好像是因為定義父類別的指標去指向其衍伸類別, 最後要delete時只會呼叫到父類別的dtor,所以把父類別的dtor加上virtual。 不過,要怎把這個觀念應用在這個問題上呢?

03/05 00:52, , 2F
template吃的型態在compile time就決定了 他會每個版本都
03/05 00:52, 2F

03/05 00:53, , 3F
編譯一份 來應付你丟進去的型態
03/05 00:53, 3F

03/05 00:54, , 4F
不同型態就是做個struct,第一個欄位是資料,第二個欄位是type
03/05 00:54, 4F

03/05 00:54, , 5F
第三個欄位是下個節點指標.把這個結構做成linked list
03/05 00:54, 5F
我目前就是這樣做,不過list的dtor會無法分辨型態...

03/05 00:55, , 6F
除非你要塞的東西都毫無關係 否則可以用繼承
03/05 00:55, 6F

03/05 00:56, , 7F
linked list 裡面就存它們 parent 的 pointer 這樣
03/05 00:56, 7F
恩....不太懂....可以詳細解釋給我聽嗎?

03/05 00:59, , 8F
typecode不是個好主意...
03/05 00:59, 8F
我也這麼覺得~

03/05 01:02, , 9F
話說如果C++有像Java那種共同的Object祖先就簡單了
03/05 01:02, 9F

03/05 01:11, , 10F
dtor?應該要用void轉各型態及各型態轉void吧
03/05 01:11, 10F
抱歉~dtor是省略寫法,應該是destructor。

03/05 01:12, , 11F
或者是void指標指向各資料單位,看什麼型態就怎麼解.
03/05 01:12, 11F

03/05 01:12, , 12F
你的A類B類繼承共同的父類別, list節點的dataPtr型態
03/05 01:12, 12F

03/05 01:12, , 13F
改成 : 父類別*
03/05 01:12, 13F
喔喔~對耶! 然後父類別的destructor用virtual修飾。 我懂了~感謝! ※ 編輯: kkroy 來自: 61.230.181.215 (03/05 02:00)
文章代碼(AID): #1BZ-EXYi (C_and_CPP)
文章代碼(AID): #1BZ-EXYi (C_and_CPP)