View Full Version : How to store custom class in QHash?

6th August 2008, 23:25

I have written a class User. Its a simple class which stores some information about user. Here is a code:


#ifndef USER_H
#define USER_H

#include <QObject>
#include <QString>
#include <QHostAddress>
#include <QDateTime>
#include <QDataStream>

class User : public QObject

User(QString &firstName, QString &lastName);
User(const User &newUser);
void setIpAddress(const QHostAddress &newIpAddress);
void setConnectionDateTime(const QDateTime &newConnectionDateTime);
void setFirstName(const QString &newFirstName);
void setLastName(const QString &newLastName);
QString firstName() const {return userFirstName;}
QString lastName() const {return userLastName;}
QHostAddress ipAddress() const {return userIpAddress;}
QDateTime connectionDateTime() const {return userConnectionDateTime;}
quint16 userSize() const;
bool operator==(const User & other) const;
QString userFirstName;
QString userLastName;
QHostAddress userIpAddress;
QDateTime userConnectionDateTime;

Q_CORE_EXPORT QDataStream & operator<<(QDataStream & out, const User &user);
Q_CORE_EXPORT QDataStream & operator>>(QDataStream & in, User &user);

#endif // USER_H


#include "user.h"
#include <QByteArray>
#include <QDataStream>

:userFirstName(""), userLastName("")


User::User(QString &firstName, QString &lastName)
:userFirstName(firstName), userLastName(lastName)


User::User(const User &newUser)
userFirstName = newUser.firstName();
userLastName = newUser.lastName();
userIpAddress = newUser.ipAddress();
userConnectionDateTime = newUser.connectionDateTime();



void User::setIpAddress(const QHostAddress &newIpAddress)
userIpAddress = newIpAddress;

void User::setConnectionDateTime(const QDateTime &newConnectionDateTime)
userConnectionDateTime = newConnectionDateTime;

void User::setFirstName(const QString &newFirstName)
userFirstName = newFirstName;

void User::setLastName(const QString &newLastName)
userLastName = newLastName;

quint16 User::userSize() const
QByteArray *array = new QByteArray;
QDataStream stream(array, QIODevice::WriteOnly);
stream << userFirstName << userLastName << userIpAddress << userConnectionDateTime;
quint16 size = array->size();
return size;

bool User::operator==(const User & other) const
bool state;
if (userFirstName == other.firstName() && userLastName == other.lastName())
state = true;
state = false;

return state;

QDataStream &operator<<(QDataStream & out, const User &user)
out << user.firstName() << user.lastName() << user.ipAddress() << user.connectionDateTime();
return out;

QDataStream &operator>>(QDataStream & in, User &user)
QString firstName;
QString lastName;
QHostAddress address;
QDateTime dateTime;

in >> firstName >> lastName >> address >> dateTime;

return in;

In the other part of my program I am trying to put this class into QHash like this:

QHash<User, QTcpSocket *> connections;

But when I try to compile it i get the error message:

../../../Qt_4.3.4/include/QtCore/../../src/corelib/tools/qhash.h instantiated from `bool QHash<Key, T>::contains(const Key&) const [with Key = User, T = QTcpSocket*]'
../../../Qt_4.3.4/include/QtCore/../../src/corelib/tools/qhash.h no matching function for call to `qHash(const User&)'

What shoud I do to make possible to add this class into QHash?


6th August 2008, 23:36
QObjects can't be copied and QHash requires the key class to be mutable and have the qHash() function defined. From what I see you violated both requirements :)

Your class doesn't seem to benefit from being a QObject subclass and furthermore the serialization mechanism probably won't work with it either. I suggest you remove the QObject legacy and implement qHash for your class.

If you require your class to be a QObject, then I suggest storing pointers to those objects instead of objects themselves in the hash.

7th August 2008, 09:14

Ok, I can remove the QObject legacy but how to implement qHash for my class? Can you write a little example?

7th August 2008, 09:57
As far as I remember there is a nice example in the docs. In general the function should return an integer for any object of your class - always the same integer for the same object content and different integers for different content with an equal spread of values among the object space.