作者kkroy (☆㊣↖煞氣ㄟ阿喂↘ξ★)
看板C_and_CPP
標題[問題]
時間Fri Mar 5 00:45:19 2010
我最近一直在想這個問題,而且想用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
→ akasan:google "virtual destructor" 03/05 00:51
我有找了一下,不過就我知道的,好像是因為定義父類別的指標去指向其衍伸類別,
最後要delete時只會呼叫到父類別的dtor,所以把父類別的dtor加上virtual。
不過,要怎把這個觀念應用在這個問題上呢?
→ joefaq:template吃的型態在compile time就決定了 他會每個版本都 03/05 00:52
→ joefaq:編譯一份 來應付你丟進去的型態 03/05 00:53
推 yauhh:不同型態就是做個struct,第一個欄位是資料,第二個欄位是type 03/05 00:54
→ yauhh:第三個欄位是下個節點指標.把這個結構做成linked list 03/05 00:54
我目前就是這樣做,不過list的dtor會無法分辨型態...
→ james732:除非你要塞的東西都毫無關係 否則可以用繼承 03/05 00:55
→ james732:linked list 裡面就存它們 parent 的 pointer 這樣 03/05 00:56
恩....不太懂....可以詳細解釋給我聽嗎?
推 loveme00835:typecode不是個好主意... 03/05 00:59
我也這麼覺得~
→ james732:話說如果C++有像Java那種共同的Object祖先就簡單了 03/05 01:02
→ yauhh:dtor?應該要用void轉各型態及各型態轉void吧 03/05 01:11
抱歉~dtor是省略寫法,應該是destructor。
→ yauhh:或者是void指標指向各資料單位,看什麼型態就怎麼解. 03/05 01:12
推 loveme00835:你的A類B類繼承共同的父類別, list節點的dataPtr型態 03/05 01:12
→ loveme00835:改成 : 父類別* 03/05 01:12
喔喔~對耶! 然後父類別的destructor用virtual修飾。
我懂了~感謝!
※ 編輯: kkroy 來自: 61.230.181.215 (03/05 02:00)