Qt中 使用Json 对自定义对象进行序列与反序列化 之二

Posted 思危

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt中 使用Json 对自定义对象进行序列与反序列化 之二相关的知识,希望对你有一定的参考价值。

在使用多态的情况下,通过基类的指针列表序列化时,需保存对象的类型信息。在反序列化时通过类型信息构造正确的子类对象。代码中类型信息使用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();
}

 

以上是关于Qt中 使用Json 对自定义对象进行序列与反序列化 之二的主要内容,如果未能解决你的问题,请参考以下文章

c# 通过json.net中的JsonConverter进行自定义序列化与反序列化

C# Json之序列化与反序列化

Android 中使用Gson完成对象的序列化与反序列化

python序列化与反序列化——json与pickle

什么是json的序列化和反序列化

com.alibaba.fastjson.JSON对类对象的序列化与反序列化