2012-11-17 122 views
2

我首先定義專用模板類是否可以繼承另一個專用模板類?

class Hash 
{ 

}; 

然後散列的一個特例。

template <class T> 
class Hash<int, T> 
{ 
public: 
    Hash(int slotN = 11); 

    bool insert(int key, T val); 
    bool remove(int key); 
    bool contains(int key); 
    bool query(int key, T& val) ; 

protected: 
    // Basic Variables of the Hash Model. 
    list<int>* slot; 
    list<T>* slotVal; 
    int slotN; 
}; 

我想用哈希 的這個特殊版本來實現另一個專業化:的 字符串值爲鍵哈希。

template <class T> 
class Hash<string, T> : public Hash<int, T> 
{ 
public: 
    Hash(int slotN); 

    bool insert(string key, T val); 
    bool remove(string key); 
    bool contains(string key); 
    bool query(string key, T& val) ; 

private: 

    // Calculate the String's Hash Key. 
    int str2key(string key); 
}; 

但似乎我無法訪問類哈希中的字段。爲什麼?

+1

您的主要聲明'Hash'沒有顯示任何模板參數,所以您專門做了什麼,我對您顯示的代碼有點困惑。你能顯示具體的代碼和錯誤信息嗎? –

回答

2

當你說「我無法訪問類哈希中的字段」我想你的意思是說,當你使用Hash<string, T>(某些類型爲T)時,你不能調用Hash<int, T>中的超載函數。其原因是名稱隱藏:當您在派生類中重載成員函數時,除非使其明確可用,否則基類中具有相同名稱的所有成員都將被隱藏。做到這一點的方式是一個using聲明:

template <class T> 
class Hash<string, T> : public Hash<int, T> 
{ 
public: 
    Hash(int slotN); 

    using Hash<int, T>::insert; 
    using Hash<int, T>::remove; 
    using Hash<int, T>::contains; 
    using Hash<int, T>::query; 

    bool insert(string key, T val); 
    bool remove(string key); 
    bool contains(string key); 
    bool query(string key, T& val) ; 

private: 

    // Calculate the String's Hash Key. 
    int str2key(string key); 
}; 

如果你只是需要從您的派生類的實現訪問基類成員,您也可以使用資質與類名來訪問的名稱。例如:

template <typename T> 
bool Hash<string, T>::insert(string key, T val) { 
    return this->Hash<int, T>::insert(this->str2key(key, val); 
} 

思考多一點的問題,還有一個潛在的問題:如果你訪問的數據成員在基類中,你需要確保的是,編譯器將認爲名稱的從屬名稱。否則它是在第一階段擡頭一看,不會在基地的名稱,因爲只能在第二階段中發現:

template <typename T> 
bool Hash<string, T>::insert(string key, T val) { 
    int n0 = slotN; // doesn't work: looked up in phase 1 
    int n1 = this->slotN; // OK: name is dependent 
    int n2 = Hash<int, T>::slotN; // OK, too 
} 

就個人而言,我不會公開從類派生使用不同的密鑰,但我假設你有你的理由。順便說一句,我認爲你的Hash初級聲明看起來是這樣的,雖然它不會爲這個問題無關緊要,真正做到:

template <typename K, typename T> 
class Hash; 

(如果它不具有任何成員,我寧願不定義它,其一)。