2014-01-17 4 views
0

У меня есть класс ContactData и класс FriendList, в котором есть QList, и я перегрузил операторы </>> </>>.Сохраните и загрузите QList <Class*> в файл


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. Это где я застрял ..

Может кто-нибудь Помогите?

+0

Из кода: для (INT I = 0; i < list-> size(); i ++) для самого десериализационного списка. когда список пуст (и вы хотите его загрузить), size() вернет 0, поэтому ничего не будет десериализовано. Вы должны (попытаться) десериализовать до тех пор, пока поток не закончится (или не запишите размер списка в начале). –

+0

У вас есть ошибка в коде. Ваш << оператор ожидает 'FriendList &', но вы даете 'FriendList *' –

ответ

0

От вашего кода, чтобы восстановить список:

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

Проблема заключается в том, что, когда вы десериализации в пустой список size() возвращает 0 (или значение совершенно не связанного с тем, что вы должны прочитать с диска) и в любом случае вам нужно читать элементы из потока, это не имеет значения для фактического размера списка. Кроме того, список пуст, поэтому вы должны сначала создать новый элемент (вы не можете просто вызвать 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 в комментариях, если у вас нет какой-либо ошибки во время сериализации, вероятно, это просто опечатка, но ...

+1

Это получилось хорошо, спасибо. – Dunkelbunt27

+0

@ Dunkelbunt27 вы приветствуете! –

2

Вам не нужно перегружать операторы >> и << для QList, они уже существуют, когда оператор Левого QDataStream

см the documentation

Пока отдельный объект может сериализацию и deserialise правильно , все контейнеры Qt также должны сериализоваться и десериализоваться.

0

Спасибо всем, кто подал помощь, теперь он отлично работает для меня. Для тех, кому интересно, вот то, что я должен был изменить:

функция экономии

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

 Смежные вопросы

  • Нет связанных вопросов^_^