В Qt есть замечательные контейнеры для самых различных задач и ситуаций. В том числе ассоциативные массивы QMap и QHash. В качестве ключей для этих контейнеров можно использовать многие стандартные классы Qt, но иногда может возникнуть необходимость в собственной реализации ключа, для этого нужно реализовать несколько методов в собственном классе, а именно - для QMap достаточно определить оператор меньше (bool operator<), а для QHash - оператор равно (bool operator==), а также перегрузить функцию uint qHash() принимающую в качестве параметра объект нашего класса ключа. Далее приведен код класса CustomKey, который можно использовать как ключ для QMap и QHash, с реализацией всех необходимых методов, а также код демонстрирующий использование данного класса, и в качестве бонуса - различные способы обхода Qt контейнеров, в том числе, способы основанные на возможностях стандарта с++11 (auto, range-based for loops).
customkey.h
#define CUSTOMKEY_H
#include <QHash>
class CustomKey
{
public:
CustomKey(const int &id = 0);
int id() const {
return m_id;
}
bool operator< (const CustomKey &other) const {
return id() < other.id();
}
bool operator== (const CustomKey &other) const {
return id() == other.id();
}
private:
int m_id;
};
inline uint qHash(const CustomKey &key, uint seed) {
return qHash(key.id(), seed);
}
#endif // CUSTOMKEY_H
main.cpp
#include <QCoreApplication>
#include <QMap>
#include <QMapIterator>
#include <QHash>
#include <QHashIterator>
#include <QDebug>
#include "customkey.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QMap<CustomKey, QString> map;
QHash<CustomKey, QString> hash;
for (int i = 0; i < 5; ++i) {
map.insert(CustomKey(i), QString::number(i));
hash.insert(CustomKey(i), QString::number(i*10));
}
/*
* Index
*/
qDebug() << "Indexing:\nQMap value";
for (int i = 0; i < 5; ++i) {
qDebug() << map[i];
}
qDebug() << "QHash value";
for (int i = 0; i < 5; ++i) {
qDebug() << hash[CustomKey(i)];
}
/*
* STL style iterators for QMap and QHash
*/
qDebug() << endl << "STL style:" << endl << "Key, value. QMap";
for (auto it = map.begin(); it != map.end(); ++it) {
qDebug() << it.key().id() << it.value();
}
qDebug() << "Key, value. QHash";
for (auto it = hash.begin(); it != hash.end(); ++it) {
qDebug() << it.key().id() << it.value();
}
/*
* Java style iterators for QMap and QHash
*/
qDebug() << endl << "Java style:" << endl << "Key, value. QMap";
QMapIterator<CustomKey, QString> mapIt(map);
while (mapIt.hasNext()) {
mapIt.next();
qDebug() << mapIt.key().id() << mapIt.value();
}
qDebug() << "Key, value. QHash";
QHashIterator<CustomKey, QString> hashIt(hash);
while (hashIt.hasNext()) {
hashIt.next();
qDebug() << hashIt.key().id() << hashIt.value();
}
/*
* The foreach keyword for QMap and QHash
*/
qDebug() << endl << "The foreach keyword:" << endl << "QMap key";
foreach (const CustomKey &key, map.keys()) {
qDebug() << key.id();
}
qDebug() << "QMap value";
foreach (const QString &str, map) {
qDebug() << str;
}
qDebug() << "QHash key";
foreach (const CustomKey &key, hash.keys()) {
qDebug() << key.id();
}
qDebug() << "QHash value";
foreach (const QString &str, hash) {
qDebug() << str;
}
/*
* Range-based for loops
*/
qDebug() << endl << "Range-based for loops:\nQMap";
for (auto it : map) {
qDebug() << it;
}
qDebug() << "QHash";
for (auto it : hash) {
qDebug() << it;
}
return a.exec();
}
P.S.: Не стоит забывать читать документацию Qt. Ссылки по теме:
1. QMap:
http://qt-project.org/doc/qt-5.0/qtcore/qmap.html#details
2. QHash:
http://qt-project.org/doc/qt-5.0/qtcore/qhash.html#details