Обычно вам нужно, чтобы ваша хеш-функция соответствовала равенству, определенному в ваших классах. Возможно, равенство определяется перегруженным operator==
, но даже если это не перегружено, вы можете подумать, что два объекта должны считаться равными и иметь одинаковый хэш-код, если все их элементы данных равны.
Хеширование необработанных байтов вообще не работает. Нет никакой гарантии, что два объекта, все элементы данных которых равны, будут иметь одинаковые байты. Например, где-то в объекте может быть некоторое заполнение по причинам выравнивания, а байты заполнения могут принимать любое значение.
Хуже того, нет никакой гарантии, что два равных значения double
имеют одинаковые байты. Например, положительный/отрицательный нуль сравнивается равным.
Случай C особенно сложен: если два объекта C указывают на разные объекты otherClass
, но два объекта otherClass
равны, то должны ли два объекта C иметь одинаковое значение хеш-функции? Вы не можете определить это в полной общности, это свойство класса C.
Может ли что-то быть «субоптимальным», если это также лучшее из возможного? ;-) Единственное общее решение - определить функцию hash
и написать версию для каждого класса. В вашем случае вы можете сделать это виртуальной функцией A, но вы также можете посмотреть, как std::hash
работает в C++0x: на самом деле это класс функтора шаблона, а не функция, и он может быть специализирован для пользовательских классов. Это, конечно, не обеспечивает динамического полиморфизма, но если вы настроите его для A
и заставите реализацию вызывать виртуальную функцию, которую вы реализуете в каждом классе, тогда ваша хеш-функция будет работать с std::unordered_map
и т. д.
person
Steve Jessop
schedule
20.11.2010