Сериализация QHash с собственным классом?

У меня есть QHash<const QString id, MyClass> , тогда как MyClass — это просто набор некоторых значений QString quint8 с геттерами и сеттерами. MyClass также имеет перезаписанный QDataStream &operator<<(QDataStream &ds, const MyClass &obj).

Для сериализации я использую:

typedef QHash<const QString, MyClass> MyClassHash;
//..
QDataStream &operator<<(QDataStream &ds, const MyClassHash &obj) {

    QHashIterator<const QString, MyClass> i(obj);

    while(i.hasNext())
    {
        i.next();
        QString cKey = i.key();
        ds << cKey << i.value();
    }

    return ds;
}

Теперь меня смущает другое:

QDataStream &operator>>(QDataStream &ds, MyClassHash &obj) {
    obj.clear();

    // ?    

    return ds;
}

Хотел бы я знать длину этого сериализованного QHash?


person Ralf Wickum    schedule 26.10.2015    source источник


Ответы (3)


Как насчет QDataStream::status:

QDataStream &operator>>(QDataStream &ds, MyClassHash &obj) {
  obj.clear(); // clear possible items

  Myclass cMyCls;

  while (!ds.status()) { // while not finished or corrupted
    ds >> cKey >> cMyCls;
    if (!cKey.isEmpty()) { // prohibits the last empty one
      obj.insert(cKey, cMyCls);
    }
  } 

  return ds;
}
person Murat    schedule 26.10.2015

Вы не предоставляете operator<< и operator>> для QHash; их реализация уже предоставлена ​​вам Qt.

Пока и ваш тип ключа, и ваш тип значения сериализуемы с помощью QDataStream, все готово:

class MyClass
{
    int i;
    friend QDataStream &operator<<(QDataStream &ds, const MyClass &c);
    friend QDataStream &operator>>(QDataStream &ds, MyClass &c);
};

QDataStream &operator<<(QDataStream &ds, const MyClass &c)
{
    ds << c.i;
    return ds;
}
QDataStream &operator>>(QDataStream &ds, MyClass &c)
{
    ds >> c.i;
    return ds;
}

int main() 
{
    QHash<QString, MyClass> hash;
    QDataStream ds;
    // doesn't do anything useful, but it compiles, showing you
    // that you don't need any custom streaming operators
    // for QHash
    ds << hash;
    ds >> hash;
}
person peppe    schedule 26.10.2015

Очевидно, что есть два способа сделать что-то:

  1. В operator<< перед сохранением элементов QHash вы должны сохранить QHash::size
  2. В конце operator<< сохраните какую-нибудь недопустимую QString, например пустую QString, а в operator>> прекратите чтение, когда встретим такое значение.
person fghj    schedule 26.10.2015