2012-02-12 151 views
1
template<class KEY, class VALUE> 
unsigned int HashMap<KEY, VALUE>::hashCode(KEY key) 
{ 
    unsigned int k = key & 0xffffffff; //error: no match for ‘operator&’ in ‘key & 4294967295u’ 
    k += ~(k<<9); 
    k ^= (k>>14); 
    k += (k<<4); 
    k ^= (k>>10); 
    return k; 
}; 

正如你所看到的,我试图通过操纵对象中的位来实现hashCode。显然,位操作符不容易应用于用户定义的对象。HashMap的实现:--- hashcode

我想取一些任何类型的对象给定它的内存位置,并按照我的意愿操作这些位。然后,我将重新解释这些位为int并将位运算符应用于int。

这听起来像个好主意吗?我怎样才能从任何类型的对象在给定的内存位置?

非常感谢!

回答

2

不,这是一个可怕的想法,因为它不尊重类型的平等定义。一个类型可能被定义为使得几个不同的表示可以被认为是相等的(想想一个std::string,它包含一对指针,没有别的。两个字符串可能是相等的(都包含"hello world",但有不同的指针,因为它们指向不同的指针块的内存,所以你的散列键实现将返回不同的散列键两个相等的对象。

换句话说,你会破坏散列表,用户将无法找到他们放在表中的对象。

+0

这是全部的事实。 – StilesCrisis 2012-02-12 17:00:45

1

这不是一个好主意。

不知道对象的成员的详细信息,你不知道哪些位实际上是有用或散列相关。例如,由于对齐问题,实际数据成员之间可能存在内存空白,并且间隙不会被初始化,因此它们充满了垃圾数据。或者,如果数据成员是一个char数组字符串,那么经过空终止符的所有字节都是垃圾,并且不应该对散列做出贡献。

有一些方法可以在C++中使用宏来实现简单的反射,这些宏可以在这里做你真正想要的东西(即查找所有结构的成员和类型),但是我不知道顶部有什么好的开源代码。我的头。我们的代码库中有一个工作正常(它有一个模板,它完全符合你的要求,即为任意结构创建散列函数),但我无法共享它。

0

我想取一些任何类型的对象,给定它的内存位置,并按照我的意愿操作这些位。

你在这里说的是你想操作数据结构的底层位表示作为一系列位。

这种方法只能用于原始类型,例如整数,字符等

在你的例子中KEY可能是任何东西,底层的位和结构的大小差不多,所以你的and操作并没有真正的帮助。

此外KEY可能是一个派生类,并开始击中作为底层结构的一部分的虚拟指针地址等。

在任何情况下,我认为代码(即使你决定这样做,还有一些SO的朋友专家可以指导你)。

最好的办法是给每个object.This成员hash是遵循的方法在Java中,至少是直接实现

+1

由于对齐会留下间隙,并且char数组在空终止符后面有垃圾,所以它不能在基元类型上工作。有关详细信息,请参阅我以前的答案。 – StilesCrisis 2012-02-12 17:00:09

+0

你是对的。我记得在java中的实际原始数据,例如int的散列值就是数字本身 – Cratylus 2012-02-12 19:21:49