PDA

View Full Version : QTList Custom class Serlization



saravanadel
19th January 2012, 14:10
Hi,

I have a problem in qt list serialization.

I am getting error no match for operator '>>' in s '>>' t (from qdatastream.h). I also tried declaring meta but not use.



class CustomClass
{
QString name;
QDataStream &operator<<(QDataStream &out, const CustomClass& myClass)
{
out<<myClass.name;
return out;
}
QDataStream &operator>>(QDataStream& in,CustomClass& myClass)
{
in>>myClass.name;
return in;
}
}
Q_DECLARE_METATYPE(CustomClass*);

class CustomClass2
{
QList<CustomClass> list;
QDataStream &operator<<(QDataStream &out, const CustomClass2& myClass)
{
out<<myClass.list;
return out;
}
QDataStream &operator>>(QDataStream& in,CustomClass2& myClass)
{
in>>myClass.list;
return in;
}
};

Without the meta tag declaration 'Q_DECLARE_METATYPE(CustomClass*);'. it says no match for operator '>>' and '<<' myClass.list

Please help.


Development in,
Qt SDK for Nokia

wysota
19th January 2012, 14:12
Define the operators as standalone functions and not methods of your class.

ChrisW67
19th January 2012, 22:41
Without the meta tag declaration 'Q_DECLARE_METATYPE(CustomClass*);'. it says no match for operator '>>' and '<<' myClass.list

With the macro in place you will receive an error because CustomClass declaration is missing a terminating semi-colon.

After doing as wysota suggests you may also need to make the free operator functions friends of the class.

saravanadel
20th January 2012, 05:35
Define the operators as standalone functions and not methods of your class.

Still the same.

no match for 'operator >>' in 'in >> myClass.list'

I missed the semi-colon in the post.

Added after 41 minutes:


Define the operators as standalone functions and not methods of your class.

It worked when I declared them inline in h.

Secondly I cannot serialize the objects to the datastream.

QList<CustomClass*> list;
QDataStream out(&file);
out <<list; //works fine

QList<CustomClass*> ob;
QDataStream in(&file);
in >>ob; //no match for operator' >> in s >> t'

I more thing, I am inheriting CustomClass from QObject.

ChrisW67
20th January 2012, 05:50
Congratulations. Would you like us to guess what you have actually done? Clearly it wasn't what wysota and I suggested because I know that works.

Edit... since you added to your prior post:

In your header you should have a prototype for the operator>> and operator<< free functions.
In your cpp you should have the implementation. Just like you do for the classes.

You are probably streaming a series of pointer values to a store, not the content of the pointed-to objects. This does not bode well for recovering the objects. What do your actual streaming operators look like?

saravanadel
20th January 2012, 06:31
What do your actual streaming operators look like?

inline QDataStream& operator<<(QDataStream &out, const ContactModel& myClass)
inline QDataStream& operator>>(QDataStream& in,ContactModel& myClass)

ChrisW67
20th January 2012, 07:31
Those operators have nothing to do with your last example.

This does not do what you think it does:


QList<CustomClass*> list;
QDataStream out(&file);
out <<list; //works fine

Trace the execution and look at the actual data written to the file. Your streaming operator for CustomClass:


QDataStream &operator<<(QDataStream &out, const CustomClass& myClass)

is not being used. The pointers are being streamed as booleans.

When you have worked out why then you can tackle the second part with some understanding.

saravanadel
20th January 2012, 08:21
QList<CustomClass*> list;

Is there any way to write the values of the qlist rather than streaming the pointers.

If I declare 'QList<CustomClass>' it says Object is private, since the copying is not allowed. (But I can do this with inheriting QObject which I dont want)

wysota
20th January 2012, 10:54
If an operator for streaming CustomClass objects looks like this:

QDataStream &operator<<(QDataStream &out, const CustomClass& myClass)
Then what will an operator for streaming CustomClass* look like?

ChrisW67
20th January 2012, 10:58
Perhaps use the * operator to deference each pointer


out << list.size();
foreach(CustomClass* p, list)
out << *p;

saravanadel
20th January 2012, 11:59
Perhaps use the * operator to deference each pointer


out << list.size();
foreach(CustomClass* p, list)
out << *p;


This is how I am using now.

ChrisW67
20th January 2012, 20:36
Huh :confused: Nowhere in this thread have you done anything like that.
Your code:


QList<CustomClass*> list;
QDataStream out(&file);
out <<list; //works fine


My code:


QList<CustomClass*> list;
QDataStream out(&file);
out << list.size();
foreach(CustomClass* p, list)
out << *p;


Wysota's prompting would give you something that would make your code work.
My code gives you another way to do it using the operator<<() for CustomClass that you already have.

wysota
20th January 2012, 21:49
Effectively the operator would do more or less the same :)

Just a word of warning -- if you use the solution provided by Chris, you have to serialize size of the list as well otherwise while deserializing you won't know how many items to read.