我首先定义了
class Hash
{
};
然后是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;
};
我想使用这个特殊版本的Hash 实现另一个专业化:Hash of 字符串值键。
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);
};
但似乎我无法访问Hash类中的字段。为什么呢?
答案 0 :(得分:2)
当你说“我无法访问Hash类中的字段”时,我想你的意思是,当你使用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;
(如果它没有任何成员,我宁愿不定义它。)