2011-05-25 26 views
2

(第一多個不同類型,作爲一個聲明,這是關係到一個任務。我不要求任何人來爲我做我的任務,只是嘗試和幫助我瞭解如何正確地實現模板)在鏈接列表使用C++模板,與出現在列表中

我目前的設置是:

我有A類,這是一個基類。 B,C和d級A類的所有兒童

我試圖做一個鏈表,一個單獨的列表中,可以指向B,C或D.

我目前有設置是這樣的:

enum Types { TypeB, TypeC, TypeD } 

struct Node 
{ 
    void * pointerToElement; 
    int type; 
    Node * next; 
}; 

struct Header 
{ 
    int counter; 
    Node * first; 
}; 

這實際上的作品。當我經過鏈表來打印出所有的元素,我用的是和if語句和int type找出什麼樣的是(基於定義的ENUM),然後用static_cast到空指針轉換爲一個指針無論是B級,C或D.

現在,我已經告訴我需要使用模板來代替,這是造成一大堆頭痛。我對模板沒有太多的瞭解,但我的經驗並不令人愉快。

我對模板的理解是,我可以用它來定義整個鏈表,只要有B,C或D類,但是B,C或D都出現在同一個鏈表中卻不合理?

我曾嘗試以下:

enum Types { TypeB, TypeC, TypeD } // I realise that if templates work, I won't need this 

template <class T> 
struct Node 
{ 
    T * pointerToElement; 
    int type; 
    Node<T> * next; // Reason 1 I suspect I could only use one type 
}; 

template <class T> 
struct Header 
{ 
    int counter; 
    Node<T> * first; // Reason 2 I suspect I could only use one type 
}; 

主要的問題我有,是模板應該是能夠做到這一點?當在一個類中實現它時,我需要爲頭部指定一個類型,這是我不想做的,所以我也將該類作爲模板,並且一直遵循我的代碼的其餘部分, t需要成爲一個模板,並最終到達main(),在那裏我不得不定義B類,C類或D類。

意見和建議表示讚賞。

謝謝。

編輯

感謝大家的意見,我可能已經學會了更多嘗試這一然後從講座。

我所做的一切是相當多拋棄的模板,或者至少我試圖用他們的方式。我已經使用了模板(不幸的是爲了使用模板),它的工作原理。這就是我現在已經做了

template <class T> 
struct Node 
{ 
    T * pointerToElement; 
    int type; // I can get rid of this after I go through the code and remove all references to it, which I am doing now. 
    Node<T> * next; // Reason 1 I suspect I could only use one type 
}; 

template <class T> 
struct Header 
{ 
    int counter; 
    Node<T> * first; // Reason 2 I suspect I could only use one type 
}; 

仍然會是這樣,但在宣佈頭時,我聲明爲(全部來自所有有用的意見制定了...謝謝!):

標題* myHeader;

(我使用的一類結構上與一個在下面的溶液中)。

所以這是指向基類,所有的其他類衍生自所述一個。然後,由於繼承,我可以將類B,C或D存儲在那裏,沒有任何問題,並且規定派生類(B,C和D)中定義的所有函數都在基類中定義,我可以稱之爲直接而不必強制轉換(例如,它們都有自己的打印功能,並且在派生類中定義它時會調用正確的打印功能)。

我認爲這個想法是,分配試圖穿過得到的是一個鏈接列表,可以與任何類型的使用,我覺得有一些誤傳(可能主要是由於我)是我認爲的模板被認爲是用於在每個節點中定義不同的類類型,而不是用於定義基類。

+1

這聽起來像一個繼承工作 – GWW 2011-05-25 01:53:40

+0

有點不喜歡,但一個好的功課問題+1。 – 2011-05-25 01:55:00

+0

GWW:B類,C類和D類都是從A類繼承而來的。在實際的任務中,它是模擬銀行,所以A類是Account,B,C和D是儲蓄,支票或信用賬戶。這個想法是,每個客戶都有一個鏈接的賬戶列表,他們的賬戶可以在任何時候,顯然我需要使用模板來滿足標記標準(我使用void *)。我想我最終可能會在作業中的其他地方投擲模板。 John:謝謝。 – joshhendo 2011-05-25 02:01:44

回答

1

而不是您應該使用繼承的模板。正如你猜測的那樣,模板根據類型T創建實例,這不是你想要的。

你的代碼應該是在這些線路:

class A{...}; 
class B: public A{...}; 
class C: public A{...}; 
class D: public A{...}; 
struct Node{ 
    A *next; 
} 

可以分配給next三分球要麼ABCD。確保在適當的地方將成員函數標記爲virtual

+0

我在想這就是我最終會做的。只是一個簡單的問題,如果B類具有C類不具備的功能,那麼即使它不出現在所有派生函數中,在A類中將其定義爲虛函數也可以嗎? – joshhendo 2011-05-25 02:20:45

+1

@joshhendo - 如果它是一個純虛擬函數(即:在A類中,這個函數沒有主體,只是後面帶有'= 0'的聲明),那麼所有派生類都必須實現它。如果A具有其實現,那麼C將繼承該實現,除非它具有它自己的實現。在任何情況下,當遍歷列表時,只能訪問爲A定義的成員函數和變量,除非將其轉換爲其他內容(使用'dynamic_cast'而不是'static_cast',瞭解差異和用法) 。 – littleadv 2011-05-25 02:25:01

+1

@joshhendo:看看[SOLID](http://en.wikipedia.org/wiki/Solid_(object-oriented_design))原則,特別是[Liskov替代原則](http:// en。 wikipedia.org/wiki/Liskov_substitution_principle)。在精心設計的程序中,如果編寫一個使用A類型對象的操作,則應該能夠用B,C或D類型的對象代替它,並且該程序仍然應該是正確的。 (簡而言之,儘管C++允許你這麼做,但是你說的並不好。) – Karmastan 2011-05-25 02:30:37