0

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


联系人数据.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);

联系人数据.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;
}

好友列表.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);

好友列表.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 的空列表。这就是我卡住的地方..

任何人都可以帮忙吗?

4

3 回答 3

3

您不需要为 重载>>and<<运算符QList,当左手运算符是时它们已经存在QDataStream

文档

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

于 2014-01-17T15:34:07.800 回答
1

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

保存功能

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

好友列表.cpp

QDataStream &operator>>(QDataStream& in, FriendList* list)
{
    while (!in.atEnd())
    {
        ContactData* contact = new ContactData();
        in >> contact;
        list->m_list->push_back(contact);
    }
    return in;
}
于 2014-01-18T22:35:11.683 回答
1

从您的代码重建列表:

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

要完成检查卡米尔在评论中所说的内容,如果您在序列化过程中没有任何错误,可能只是一个错字,但是......

于 2014-01-17T12:59:02.703 回答