2011-12-05 188 views
0

簡單問題在這裏。我必須定義包含書籍,電影,CD集的類。我定義了一個模板類,說Set<T>,所有來自特定情況下獲得的常用方法,然後定義類(是正確的說法?)的Set從模板類的實例繼承

class Movies_set : public Set<Movie> 
{ 
    /* ... */ 
} 

中,我定義了一些其他的方法(說一個搜索演員的函數)。這是一種很好的編程技術,還是有更方便的方法?

+0

「Movies_set」和「Set 」之間的功能區別是什麼? –

+0

例如,一個Movies_set可以有一個方法來搜索一個actor,而通用Set僅僅是一個在標題中搜索的方法(所有的類Movie,Book,Album都有一個'search_in_title'方法) – Pincopallino

+0

這似乎有點關閉。如果'Set '對'Movie'沒有專門的行爲,那麼名爲'Movies_set'的重複排序也不應該。如果不相同,我預計這兩種類型是等同的。 –

回答

3

這取決於實際設置的是什麼。我懷疑Set是類似於std :: set的東西,在這種情況下,我會建議反對派生,並引導你朝向構圖。

從Set派生出來的原因是一個壞主意,因爲它公開了set的API,它與MovieSet沒有任何關係。如果您需要對MovieSet對象進行搜索的方法,請在MovieSet自身上執行它們,尤其是如您所指出的那樣,您將擴充MovieSet的界面。

這樣,你也可以獲得非常強大的東西:封裝。如果由於某種原因您決定從Set更改爲std :: map,那麼您的基類的接口可能會更改,並且訪問MovieSet的任何代碼都將受到影響。如果您將Set存儲爲私有數據成員,則不會遇到此問題,因爲您已經定義了MovieSet的相應訪問器。

當然,如果全部基於我的前提,Set實際上只是一個容器。

+0

+1提到作爲替代子類化的作文 – kol

+0

我明白你在說什麼。我使用這種方法是因爲類Movie_set,Books_set和Album_set有許多共同的方法,比如'Add','Remove','search_in_title',所以我認爲在相同的模板類中實現它們會更快。 – Pincopallino

+0

然後我建議你有一個Movie_set,Book_set和Album_set的公共基類,讓我們說Media_set,知道如何搜索這些相似的對象類型。 此外,看起來您需要一個名爲Media的類,它是Movie,Book和Album的基類,如果還不是這樣的話。 – fronsacqc

0

這樣做絕對沒有錯,這是一個很常見的習慣用語。也就是說,你可能想確保一個typedef就足夠了。如果您Movies_set沒有增加新的特定功能,但它可能會更好:

typedef Set<Movie> Movies_Set; 

顯然,如果Movies_set引入特定功能相關的電影,繼承是要走的路。

0

這絕對沒問題。

事實上,有一個公知的圖案,其做幾乎類似的事情,不同的是它採用的派生類本身作爲類型參數的基類的模板:

+1

我不認爲這是事實,他沒有將基礎傳遞給泛型,他將第三種類型傳遞給基礎。並將該組合作爲新的子類型進行別名。 – 111111

+0

@ 111111:正確。我忽略了這一點。編輯帖子。 – Nawaz

0

如果Movie_set沒有添加任何超過Set的實現那麼這是浪費時間從集合

你最好是typedefing它。

typedef Set<Movie> movie_set; 

那樣。然而,如果你正在使用新的成員函數和數據成員來進一步專注於Set,那麼雖然派生自不常見的容器(通常是你自己擁有它們),但這也是可以的。但只要必要的功能是虛擬的(析構函數),它應該是可以的。