class CKDrawBase:
{
public:
friend QDataStream & operator << (QDataStream &dataStream, CKDrawBase &drawBase);
friend QDataStream & operator >> (QDataStream &dataStream, CKDrawBase &drawBase);
}
很显然,一个用于流出,一个用于流入。
对于一个简单类的序列化重载两个操作符即可,对一个多态类象这样声明:
class CKDrawBase:public QObject
{
Q_OBJECT
public:
virtual void save(QDataStream &dataStream);
virtual void load(QDataStream &dataStream);
friend QDataStream & operator << (QDataStream &dataStream, CKDrawBase &drawBase);
friend QDataStream & operator >> (QDataStream &dataStream, CKDrawBase **drawBase);
//其他的成员
};
虚函数save()和load()分别用于实际流入流出的实现,由重载操作符函数调用,这样子类就无须实现重载操作符函数,只须根据需要重载save()和load()即可。
子类如下声明:
class CKDrawLine:public CKDrawBase
{
Q_OBJECT
public:
void save(QDataStream &dataStream);
void load(QDataStream &dataStream);
//其他的成员
};
class CKDrawRectangle:public CKDrawBase
{
Q_OBJECT
public:
void save(QDataStream &dataStream);
void load(QDataStream &dataStream);
//其他的成员
};
重载<<函数实现:
friend QDataStream & operator << (QDataStream &dataStream, CKDrawBase &drawBase)
{
dataStream << QString(drawBase.metaObject()->className());//将对象的类名写入流中
drawBase.save(dataStream);
return dataStream;
}
在函数中,首先将对象的类名写入流中,然后调入save()函数,实现具体的数据流入。
重载>>函数实现:
QDataStream & operator >> (QDataStream &dataStream, CKDrawBase **drawBase)
{
QString str;
dataStream >> str;
*drawBase = NULL;
if (str == QString("CKDrawLine")) //根据类名字符串生成相应类的对象
{
*drawBase = new CKDrawLine;
(*drawBase)->load(dataStream);
return dataStream;
}
if (str == QString("CKDrawRectangle"))
{
*drawBase = new CKDrawRectangle;
(*drawBase)->load(dataStream);
return dataStream;
}
return dataStream;
}
在函数中,先读出保存的类名,然后根据相应的类名生成相应的对象,生成的对象指针保存在*drawBase中。
使用:
上述程序编写好后,就可以使用了。
例:
声明了一个QList对象QList drawList,要将其保存到文件中,或从文件中读出:
保存:
dataStream << drawList.count();//dataStream为QdataStream类型。
QList::const_iterator i;
for (i=drawList.constBegin();i!=drawList.constEnd();++i)
{
dataStream << *(*i);
}
读出:
int count;
CKDrawBase *ptr;
dataStream >> count; //dataStream为QdataStream类型。
for (int i=0; i<count;++i)
{
dataStream >> &ptr;
if (ptr != NULL)
{
drawList.append(ptr);
}
}