对象序列化,
简单地讲就是把程序运行时保存在内存中的某个对象,整个抽取出来,从而可以实现将这个对象进行持久性保存(如普通文件存储、数据库),或者网络传输。
今天在一个QT项目上刚好有这样的一个需求,网上也看了一些资料,主要的思想就是就是利用QDataStream,重载其<< 和 >>
操作符实现(虽然重载的原因是因为 QDataStream << 和 >>
操作符只支持C++内置的基本数据类型,但我觉得实际上,重载操作符过后本质上并没有什么变化,因为你必须去实现operator重载的内部实现,而在实现的过程中,依然必须以基本数据类型为单位进行写入)。现在将QT的测试代码整理出来:
DataClass.h
#ifndef DATACLASS_H
#define DATACLASS_H
#include <QDataStream>
#include <QObject>
#include <QtCore>
#include <queue>
using namespace std;
class DataClass : public QObject
{
Q_OBJECT
public:
explicit DataClass(QObject *parent = 0);
public:
int id;//数据项
QString name;//数据项
queue<int> que;//数据项
public:
friend QDataStream &operator<<(QDataStream & , const DataClass &);
friend QDataStream &operator>>(QDataStream & , DataClass &);
signals:
public slots:
};
#endif // DATACLASS_H
DataClass.cpp
#include "dataclass.h"
DataClass::DataClass(QObject *parent) : QObject(parent)
{
}
QDataStream & operator<<(QDataStream & output, const DataClass &obj)
{
output << obj.id <<obj.name;
queue<int> tmpQue = obj.que;
while(!tmpQue.empty())
{
output<<tmpQue.front();
tmpQue.pop();
}
return output ;
}
QDataStream & operator>>(QDataStream & input, DataClass & obj)
{
input >> obj.id >>obj.name;
while(!input.atEnd())
{
int elem;
input >> elem;
obj.que.push(elem);
}
return input;
}
MainWindow 序列化按钮点击事件:
void MainWindow::on_pushButton_clicked()
{
//序列化按钮单击事件
DataClass obj;
obj.id = 888;
obj.name = "tobin";
obj.que.push(999);
obj.que.push(888);
obj.que.push(777);
QFile f("D:/serialization.txt");
if(!f.open(QIODevice::WriteOnly | QIODevice::Text))
{
qDebug() << "文件打开失败!" ;
return;
}
QDataStream ds(&f);
ds << obj ;
f.close();
qDebug()<<"序列化保存成功!";
}
MainWindow 反序列化 按钮点击事件:
QFile f("D:/serialization.txt");
if(!f.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "文件打开失败!" ;
return;
}
QDataStream ds(&f);
DataClass obj;
while(!ds.atEnd())
{
ds >> obj;
}
qDebug()<<"反序列化完成,obj的id为"<<obj.id<<" name 为:"<<obj.name;
queue<int>tmpQue = obj.que;
while(!tmpQue.empty())
{
qDebug()<<tmpQue.front();
tmpQue.pop();
}
f.close();
运行效果: