QMultiHash and values of class pointers

368 Views Asked by At

Consider the following small code:

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;
}

The output is Inserted!! and this is expected because the hash compares the pointer value and not the content.

Is there a way to check for duplicates without the need to iterate over the entries with keys of 24?

2

There are 2 best solutions below

0
On

Of course it is inserted. Because you are comparing pointers (i.e. address in memory) not the person objects. And pointer p1 is of course different from p2. The simplest solution would be to store values rather than pointers in the container:

QMultiHash<int, Person> personHash; 

As a side benefit you do not need to take care of dynamic allocation and deallocation (which in this case could be a problem).

0
On

You can add a wrapper for Person - which would store pointer and provide comparison operator, and store this wrapper in your hash by value.

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;
};

You only need to be careful to avoid memory leaks - either use shared pointer, or write your own assignment and copy constructor + destructor for the wrapper class.