在使用多态的情况下,通过基类的指针列表序列化时,需保存对象的类型信息。在反序列化时通过类型信息构造正确的子类对象。代码中类型信息使用C++ typeid获取,以保证可移植性。
全部代码如下:
#include <QCoreApplication> #include <memory> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <QFile> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> class Data { public: Data(void){} Data(const std::wstring &name) : dataName(name){} virtual ~Data() {} std::wstring getName(void){ return dataName; } virtual void write(QJsonObject &json){ json["Name"] = QString::fromStdWString(dataName.c_str()); } virtual void read(const QJsonObject &json){ dataName = json["Name"].toString().toStdWString(); } virtual void print(std::wostream &out){ out << dataName.c_str() << std::endl; } private: std::wstring dataName; }; class DataAnalog : public Data { public: DataAnalog(void){} DataAnalog(const std::wstring &name, const double value):Data(name), dataValue(value) {} virtual ~DataAnalog(){} virtual void write(QJsonObject &json) override{ Data::write(json); json["Value"] = dataValue; } virtual void read(const QJsonObject &json) override{ Data::read(json); dataValue = json["Value"].toDouble(); } virtual void print(std::wostream &out){ out << getName().c_str() << L"=" << dataValue << std::endl; } private: double dataValue = 0; }; class DataDigital : public Data { public: DataDigital(void) {} DataDigital(const std::wstring &name, const bool value):Data(name), dataValue(value){} virtual ~DataDigital(){} virtual void write(QJsonObject &json) override{ Data::write(json); json["Value"] = dataValue; } virtual void read(const QJsonObject &json) override{ Data::read(json); dataValue = json["Value"].toBool(); } virtual void print(std::wostream &out) override{ out << getName().c_str() << L"=" << (dataValue?L"true":L"false") << std::endl; } private: bool dataValue = false; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); { std::vector<std::shared_ptr<Data>> datas; datas.emplace_back(new DataAnalog(L"Anlog_1", 1.1)); datas.emplace_back(new DataAnalog(L"Anlog_2", 2.2)); datas.emplace_back(new DataDigital(L"Digita_1", true)); datas.emplace_back(new DataDigital(L"Digita_2", false)); QFile file(QCoreApplication::applicationDirPath() + "\\data.json"); if(file.open(QFile::WriteOnly)) { QJsonArray dataArray; for(auto data:datas) { QJsonObject obj; obj["Class"] = typeid(*data).name(); QJsonObject dataObj; data->write(dataObj); obj["Data"] = dataObj; dataArray.append(obj); } QJsonObject json; json["Datas"] = dataArray; QJsonDocument doc(json); file.write(doc.toJson()); } } { QFile file(QCoreApplication::applicationDirPath() + "\\data.json"); if(file.open(QFile::ReadOnly)) { QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if(!doc.isNull()) { QJsonObject json = doc.object(); std::vector<std::shared_ptr<Data>> datas; QJsonArray dataArray = json["Datas"].toArray(); for(auto i : dataArray) { QJsonObject obj = i.toObject(); QString className = obj["Class"].toString(); if(className==typeid(DataAnalog).name()){ datas.emplace_back(new DataAnalog()); } else if(className == typeid(DataDigital).name()){ datas.emplace_back(new DataDigital()); } datas.back()->read(obj["Data"].toObject()); } std::for_each(datas.begin(), datas.end() , [](std::shared_ptr<Data> data){data->print(std::wcout);}); } } } return a.exec(); }
时间: 2024-10-20 06:49:53