Save and load QList<Class*> to file

帅比萌擦擦* 提交于 2020-01-03 05:36:42

问题


I have a class ContactData and a class FriendList holding a QList and I overloaded the << / >> operators.


contactdata.h

class ContactData
{
//all public for testing
public:
    ContactData();
    QString m_name;
    QString m_description;
    bool m_online; 
};

QDataStream &operator<<(QDataStream& out, ContactData& contactData);
QDataStream &operator>>(QDataStream& in, ContactData* contactData);

contactdata.cpp

QDataStream &operator<<(QDataStream &out, ContactData& contactData)
{
    out << contactData.m_name;
    out << contactData.m_description;
    return out;
}

QDataStream &operator>>(QDataStream &in, ContactData* contactData)
{
    in >> contactData->m_name;
    in >> contactData->m_description;
    return in;
}

friendlist.h

#include "contactdata.h"
typedef QList<ContactData*> TFriendList;

class FriendList
{
...
public:
TFriendList* m_list;
...
};

QDataStream &operator<<(QDataStream& out, FriendList& list);
QDataStream &operator>>(QDataStream& in, FriendList* list);

friendlist.cpp

QDataStream &operator<<(QDataStream& out, FriendList& list)
{
    for(int i = 0; i < list.size(); i++)
    {
        ContactData contact = *list.at(i);
        out << contact;
    }

    return out;
}

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    for(int i = 0; i < list->size(); i++)
    {
        ContactData* contact = list->m_list->at(i);
        in >> contact;
    }

    return in;
}

// typedef QList<ContactData*> TFriendList;
private:
    FriendList* m_friendList;

saving function

QString path = "/friendlist.bin";
QFile file(path);

if (file.open(QIODevice::WriteOnly))
{
    QDataStream out(&file);
    out << m_friendList;
    file.close();
}

loading function

QString path = "/friendlist.bin";
QFile file(path);
if(file.exists())
{
  if (file.open(QIODevice::ReadOnly))
  {
     QDataStream in(&file);
     in >> m_friendList;
     file.close();
     qDebug() << "FriendList.size() = " << m_friendList->size();
     }
}

It does save a file in the desired direction, but unfortunately loading gives me an empty list of the size 0. This is where I'm stuck..

Can anyone help?


回答1:


From your code to rebuild list:

for(int i = 0; i < list->size(); i++) 

Problem is that when you're deserializing into an empty list size() will return 0 (or a value completely unrelated to what you have to read from disk) and anyway you have to read items from stream, it doesn't matter actual list size. Moreoverlist is empty so you have first to create a new element (you can't just call at() because there aren't elements inside). You can write an integer (for example) before items then read it when deserializing:

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    int count = 0;
    in >> count;

    for(int i = 0; i < count; i++)
    {
        ContactData* contact = new ContactData();
        in >> contact;

        list->m_list->push_back(contact);
    }

    return in;
}

Do not forget to write count in serialization function too. As alternative you may read everything until end of input stream:

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    int count = 0;
    in >> count;

    while (!in.atEnd())
    {
        ContactData* contact = new ContactData();
        in >> contact;

        list->m_list->push_back(contact);
    }

    return in;
}

To finish check what Kamil said in comment, if you don't have any error during serialization probably it's just a typo but...




回答2:


You do not need to overload the >> and << operators for QList, they already exist when the left-hand operator is QDataStream

see the documentation

As long as an individual object can serialise and deserialise correctly, all Qt containers should also serialise and deserialise.




回答3:


Thanks to everyone who submitted help, now it works fine to me. For those who are interested, here is what I had to change:

saving function

if (file.open(QIODevice::WriteOnly))
{
    QDataStream out(&file);
    out << *m_friendList;
    file.close();
}

friendlist.cpp

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    while (!in.atEnd())
    {
        ContactData* contact = new ContactData();
        in >> contact;
        list->m_list->push_back(contact);
    }
    return in;
}


来源:https://stackoverflow.com/questions/21186434/save-and-load-qlistclass-to-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!