【发布时间】:2020-12-21 11:15:10
【问题描述】:
我正在尝试使用链接方法在 C++ 中构建一个哈希表类,一个最小的示例类是:
template <class V>
class HashTable {
private:
//some parameters to define the hash_table
HashFunc * h; //family of hash functions
public:
/*other functions*/
};
我在使用成员 HashFunc * h 时遇到了一些问题,这是我打算用来在哈希表中存储对 main 中,我需要构建两个不同的哈希表,一个散列整数,另一个散列字符串。
我的疑惑是:
- 对我来说,一个自然的选择是通过以下方式将多态性用于哈希函数(请注意,我对类和多态性的经验有限):
class HashFunc{
public:
virtual int operator()()=0;
}
class IntegerHashFunc: public HashFunc
{
//parameters to hash integers
public:
int operator()(int x){
//operations for integer hashing
}
}
class StringHashFunc: public HashFunc
{
//parameters to hash strings
IntegerHashFunc h_integer; //string->integer->integer hash
public:
int operator()(string name){
int result=0;
//operations for string hashing
return h_integer(result); //I need to hash the integer resulting from string "hashing"
}
}
但这不起作用,因为StringHashFunc 中的operator()(string name) 具有不同的参数,因此不会覆盖基类中的virtual 方法。如何使这项工作?
- 我不确定如何在
HashTable类的构造函数中进行这项工作:如何在两种方法之间进行选择?我是否应该在构造函数中使用一个标志,例如:
template<class V>
HashTable<V>::HashTable(/*args*/, int flag){
//other parameters
switch(flag){
case 1:
h=new IntegerHashFunc(/*args for integer hashing*/);
case 2:
h=new StringHashFunc(/*args for string hashing*/);
}
}
或者有更好的方法吗?
- 有没有更好更自然的方法来做我想做的事?例如,我尝试使用单个类
HashFunc和两个重载operator()(int)和operator()(string),但如果我只使用整数,我不想“携带”字符串参数和方法。
【问题讨论】:
-
“对我来说,一个自然的选择是使用多态性”。不。在这里停下来再想一想。是否有任何标准库容器使用多态性?为什么或为什么不?
-
一个
HashTable应该包含一个StringHashFunc和一个IntHashFunc,还是你总是只有一种类型的哈希函数? -
我是第二代词,来自不同的语言,我花了一些时间来欣赏 C++,现在运行时多态是我的最后手段,而不是像其他语言那样的 goto 解决方案
-
如果
V是那种类型,那么您希望HashTable<V>持有例如std::vector< HashFunction<V> >和HashFunction<V>有一个operator()(const V&) -
您可以从std::unordered_map 获得一些灵感。模板是去这里的方式。你甚至不需要
HashFunc类或任何东西。标准库处理它的方式你可以传递任何东西(函数、lamba、结构),只要它可以像函数一样被调用。
标签: c++ class hash polymorphism