【问题标题】:Save and load QList<Class*> to file保存并加载 QList<Class*> 到文件
【发布时间】:2014-01-17 12:48:40
【问题描述】:

我有一个 ContactData 类和一个持有 QList 的 FriendList 类,我重载了 > 运算符。


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;

保存功能

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

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

加载函数

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

它确实将文件保存在所需的方向,但不幸的是,加载给了我一个大小为 0 的空列表。 这就是我卡住的地方..

谁能帮忙?

【问题讨论】:

  • 从您的代码中: for(int i = 0; i size(); i++) 反序列化列表本身。当列表为空(并且您想加载它)时, size() 将返回 0 ,因此不会反序列化任何内容。您必须(尝试)反序列化直到流结束(或在开始时写入列表大小)。
  • 您的代码中有错误。您的 FriendList & 但您提供 FriendList *

标签: c++ qt qlist qdatastream


【解决方案1】:

您不需要为QList 重载&gt;&gt;&lt;&lt; 运算符,当左侧运算符为QDataStream 时它们已经存在

the documentation

只要单个对象可以正确序列化和反序列化,所有 Qt 容器也应该序列化和反序列化。

【讨论】:

    【解决方案2】:

    从你的代码中重建列表:

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

    问题是,当您反序列化为一个空列表时,size() 将返回 0(或一个与您必须从磁盘读取的内容完全无关的值)并且无论如何您必须从流中读取项目,它不会重要的是实际列表大小。此外list 是空的,所以你必须首先创建一个新元素(你不能只调用at(),因为里面没有元素)。您可以在项目之前写入一个整数(例如),然后在反序列化时读取它:

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

    不要忘记在序列化函数中写count。作为替代方案,您可以阅读所有内容,直到输入流结束:

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

    要完成检查 Kamil said 的评论,如果您在序列化过程中没有任何错误,可能只是一个错字,但是...

    【讨论】:

      【解决方案3】:

      感谢所有提交帮助的人,现在它对我来说很好。 对于那些感兴趣的人,这是我必须更改的内容:

      保存功能

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-04
        • 1970-01-01
        • 1970-01-01
        • 2014-11-18
        • 1970-01-01
        相关资源
        最近更新 更多