您的位置:首页 > 编程语言 > Qt开发

QT数据序列化转载及修正----我们考虑的内容科学家已经考虑过了

2014-12-12 17:11 267 查看
Qt中序列化数据的类是QDataStream,但这个类只能序列化基本类型和一部分Qt定义的类,对于自定义类需要自己编写序列化函数。

在自定义类中声明友元函数,并实现:

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 {

dataStream >> &ptr;

if (ptr != NULL)

{

drawList.append(ptr);

}

}

说明:

1、使用多态的话,必须要从QObject继承,因为要保存类名字符串。

2、每增加一个子类,都要修改重载>>函数实现,以生成相应的对象。

3、还不知道有没有更好的办法;

补充:更好的办法就是依照qt的规则声明宏和实现宏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐