Qt基类指针存储派生类数据

#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, int key) : dataName(name), m_key(key) {}

virtual ~Data() {}

 

std::string getClassName(void) {

return typeid(*this).name();

}

std::shared_ptr<Data> clone(void) const {

auto data = newData();

QJsonObject json;

write(json);

data->read(json);

return data;

}

 

std::wstring getName(void) {

return dataName;

}

int getKey()

{

return m_key;

}

 

virtual void write(QJsonObject &json) const {

json["Name"] = QString::fromStdWString(dataName.c_str());

json["Key"] = m_key;

}

virtual void read(const QJsonObject &json) {

dataName = json["Name"].toString().toStdWString();

m_key = json["Key"].toInt();

}

 

virtual void print(std::wostream &out) {

out << dataName.c_str() << std::endl;

}

 

protected:

virtual std::shared_ptr<Data> newData(void) const = 0;

 

private:

std::wstring dataName;

int m_key;

};

 

class DataAnalog : public Data

{

public:

DataAnalog(void) {}

DataAnalog(const std::wstring &name, int key, const double value) :Data(name, key), dataValue(value) {}

virtual ~DataAnalog() {}

 

virtual void write(QJsonObject &json) const override {

Data::write(json);

json["Value"] = dataValue;

json["X"] = X;

json["Y"] = Y;

json["R"] = R;

 

}

virtual void read(const QJsonObject &json) override {

Data::read(json);

dataValue = json["Value"].toDouble();

X = json["X"].toDouble();

Y = json["Y"].toDouble();

R = json["R"].toDouble();

}

 

virtual void print(std::wostream &out) {

out << getName().c_str() << L"=" << dataValue << std::endl;

}

void setData(double x, double y, double r)

{

this->X = x;

this->Y = y;

this->R = r;

}

protected:

virtual std::shared_ptr<Data> newData(void) const override {

return std::make_shared<DataAnalog>();

}

 

private:

double dataValue = 0;

double X;

double Y;

double R;

};

 

class DataDigital : public Data

{

public:

DataDigital(void) {}

DataDigital(const std::wstring &name, int key, const bool value) :Data(name, key), dataValue(value) {}

virtual ~DataDigital() {}

 

virtual void write(QJsonObject &json) const 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;

}

 

protected:

virtual std::shared_ptr<Data> newData(void) const override {

return std::make_shared<DataAnalog>();

}

 

private:

bool dataValue = false;

};

 

class DataFacotry

{

public:

static DataFacotry& instance(void) {

static DataFacotry ins;

static bool initialized = false;

if (!initialized)

{

ins.registerPrototype(std::make_shared<DataAnalog>());

ins.registerPrototype(std::make_shared<DataDigital>());

initialized = true;

}

return ins;

}

 

void registerPrototype(std::shared_ptr<Data> protoType) {

prototypeDatas.emplace(protoType->getClassName(), protoType);

}

 

std::shared_ptr<Data> create(const std::string &className) {

auto it = prototypeDatas.find(className);

if (it != prototypeDatas.end()) {

return it->second->clone();

}

return nullptr;

}

 

private:

std::map<std::string, std::shared_ptr<Data>> prototypeDatas;

};

 

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.1));

DataAnalog *A = new DataAnalog(L"Anlog_2", 2, 2.2);

A->setData(7, 8, 9);

datas.emplace_back(A);

datas.emplace_back(new DataDigital(L"Digita_1", 3, true));

datas.emplace_back(new DataDigital(L"Digita_2", 4, false));

 

QFile file(QCoreApplication::applicationDirPath() + "\\data.json");

if (file.open(QFile::WriteOnly))

{

QJsonArray dataArray;

for (auto data : datas)

{

QJsonObject obj;

obj["Class"] = data->getClassName().c_str();

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();

auto data = DataFacotry::instance().create(className.toStdString());

if (data)

{

datas.emplace_back(data);

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();

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

究极调参工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值