Рассмотрим следующий небольшой код:
class Person {
public:
QString name;
int age;
};
int main()
{
QMultiHash<int, Person*> personHash;
Person* p1 = new Person;
p1->age = 24;
p1->name = "X";
personHash.insert(p1->age,p1);
Person* p2 = new Person;
p2->age = 24;
p2->name = "X";
if(personHash.contains(p2->age,p2)) {
cout << "Duplicate!!\n";
}
else {
cout << "Inserted!!\n";
}
return 0;
}
Выход Поставлен !! и это ожидается, потому что хеш сравнивает значение указателя, а не содержимое.
Есть ли способ проверить наличие дубликатов без необходимости перебирать записи с ключами 24?
Вы можете добавить оболочку для Person, которая будет хранить указатель и предоставлять оператор сравнения, и сохранять эту оболочку в вашем хэше по значению.
class PersonPtr {
public:
PersonPtr(Person* ptrIn) : ptr(ptrIn) {};
Person* getPtr() { return ptr;}
bool operator ==(const PersonPtr &other)
{
return (other.getPtr()->name == ptr->name && other.getPtr()->age == ptr->age);
}
private:
Person* ptr;
};
Вам нужно только быть осторожным, чтобы избежать утечек памяти — либо используйте совместно используемый указатель, либо напишите свое собственное присваивание и скопируйте конструктор + деструктор для класса-оболочки.
Конечно это вставлено. Потому что вы сравниваете указатели (то есть адреса в памяти), а не объекты-личности. И указатель p1, конечно, отличается от p2. Простейшим решением было бы хранить значения, а не указатели в контейнере:
QMultiHash<int, Person> personHash;
В качестве дополнительной выгоды вам не нужно заботиться о динамическом распределении и освобождении (что в этом случае может быть проблемой).