PDA

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



Misenko
6th August 2008, 23:25
Hi

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

user.h


#ifndef USER_H
#define USER_H

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

class User : public QObject
{
Q_OBJECT

public:
User();
User(QString &firstName, QString &lastName);
User(const User &newUser);
~User();
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;
private:
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


user.cpp



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

User::User()
: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();
}

User::~User()
{

}

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

user.setFirstName(firstName);
user.setLastName(lastName);
user.setIpAddress(address);
user.setConnectionDateTime(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?

Thanks.

wysota
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.

Misenko
7th August 2008, 09:14
Thanks.

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

wysota
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.