Qt中序列化对象

转自:http://blog.tianya.cn/blogger/post_show.asp?idWriter=0&Key=0&BlogID=53411&PostID=3573216


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<count;++i)
    {
        dataStream >> &ptr;
        if (ptr != NULL)
        {
            drawList.append(ptr);
        }
    }

说明:
1、使用多态的话,必须要从QObject继承,因为要保存类名字符串。
2、每增加一个子类,都要修改重载>>函数实现,以生成相应的对象。
3、还不知道有没有更好的办法


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值