2012-11-17 89 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; 

(如果它不具有任何成员,我宁愿不定义它,其一)。