博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化
阅读量:6860 次
发布时间:2019-06-26

本文共 4323 字,大约阅读时间需要 14 分钟。

本文是基本上一篇博文进行改进而成,上一篇请见:

此处就不多说了,直接上代码。

1. 序列化基类

 

#pragma once#include 
#include
#include "json/json.h"using std::string;using std::vector;struct CJsonObejectBase{protected: enum CEnumJsonTypeMap { asArray = 1, //是数组 asJsonObj, //是复杂对象 asBool, asInt, asUInt, asString, asInt64, asUInt64, };public: CJsonObejectBase(void){}public: virtual ~CJsonObejectBase(void){} string Serialize() { Json::Value new_item = DoSerialize(); Json::FastWriter writer; std::string out2 = writer.write(new_item); return out2; } bool DeSerialize(const char* str) { Json::Reader reader; Json::Value root; if (reader.parse(str, root)) { return DoDeSerialize(root); } return false; }protected: bool DoDeSerialize(Json::Value& root) { int nSize = m_listName.size(); for (int i=0; i < nSize; ++i ) { void* pAddr = m_listPropertyAddr[i]; switch(m_listType[i]) { case asJsonObj: { if (!root[ m_listName[i] ].isNull()) ((CJsonObejectBase*)pAddr)->DoDeSerialize(root[m_listName[i]]); } break; case asBool: (*(bool*)pAddr) = root.get(m_listName[i], 0).asBool(); break; case asInt: (*(INT*)pAddr) = root.get(m_listName[i], 0).asInt(); break; case asUInt: (*(UINT*)pAddr) = root.get(m_listName[i], 0).asUInt(); break; case asInt64: (*(LONGLONG*)pAddr) = root.get(m_listName[i], 0).asInt64(); break; case asUInt64: (*(ULONGLONG*)pAddr) = root.get(m_listName[i], 0).asUInt64(); break; case asString: (*(string*)pAddr) = root.get(m_listName[i], "").asString(); default: //我暂时只支持这几种类型,需要的可以自行添加 break; } } return true; } Json::Value DoSerialize() { Json::Value new_item; int nSize = m_listName.size(); for (int i=0; i < nSize; ++i ) { void* pAddr = m_listPropertyAddr[i]; switch(m_listType[i]) { case asArray: break; case asJsonObj: new_item[m_listName[i]] = ((CJsonObejectBase*)pAddr)->DoSerialize(); break; case asBool: new_item[m_listName[i]] = (*(bool*)pAddr); case asInt: new_item[m_listName[i]] = (*(INT*)pAddr); break; case asUInt: new_item[m_listName[i]] = (*(UINT*)pAddr); break; case asInt64: new_item[m_listName[i]] = (*(LONGLONG*)pAddr); break; case asUInt64: new_item[m_listName[i]] = (*(ULONGLONG*)pAddr); break; case asString: new_item[m_listName[i]] = (*(string*)pAddr); default: //我暂时只支持这几种类型,需要的可以自行添加 break; } } return new_item; } void SetProperty(string name, CEnumJsonTypeMap type, void* addr) { m_listName.push_back(name); m_listPropertyAddr.push_back(addr); m_listType.push_back(type); } virtual void SetPropertys() = 0;private: vector
m_listName; vector
m_listPropertyAddr; vector
m_listType;};

2.测试的派生类

 

 

struct CSubTestStruct : public CJsonObejectBase{	CSubTestStruct()	{		SubMsgID = 0;		SetPropertys();	}	ULONGLONG SubMsgID;	string SubMsgTitle;protected:	//子类需要实现此函数,并且将相应的映射关系进行设置 	virtual void SetPropertys()	{		SetProperty("SubMsgID", asUInt64, &SubMsgID);		SetProperty("SubMsgTitle", asString, &SubMsgTitle);	}};struct CTestStruct : public CJsonObejectBase{	CTestStruct()	{		SetPropertys();	}	ULONGLONG MsgID;	string MsgTitle;	string MsgContent;	CSubTestStruct subObj;protected:	//子类需要实现此函数,并且将相应的映射关系进行设置 	virtual void SetPropertys()	{		SetProperty("MsgID", asUInt64, &MsgID);		SetProperty("MsgTitle", asString, &MsgTitle);		SetProperty("MsgContent", asString, &MsgContent);		SetProperty("subObj", asJsonObj, &subObj);	}};

注意,此处CSubTestStruct类型的对象是CTestStruct的一个成员.

3.测试代码及效果图

 

1). 序列化

 

void CJasonSerializeDlg::OnBnClickedOk(){	CTestStruct stru;	stru.MsgID = 11223344;	stru.MsgTitle = "黑黑";	stru.MsgContent = "哈哈";	CString strTest = stru.Serialize().c_str();	AfxMessageBox(strTest);}

效果

 

2). 反序列化

 

void CJasonSerializeDlg::OnBnClickedOk2(){	const char* pstr = "{\"MsgContent\":\"哈哈22\",\"MsgID\":11111,\"MsgTitle\":\"黑黑22\",\"subObj\":{\"SubMsgID\":3333,\"SubMsgTitle\":\"子内容\"}}";	CTestStruct stru;	stru.DeSerialize(pstr);	CString strShow = "";	strShow.Format("MsgID:%I64u\r\nMsgTile:%s\r\nMsgContent:%s\r\nSubMsgTitle:%s", stru.MsgID, stru.MsgTitle.c_str(), stru.MsgContent.c_str(), stru.subObj.SubMsgTitle.c_str());	AfxMessageBox(strShow);}

效果

 

4. 接下来要解决的问题

当对象中存在数组或者列表时,我暂时还没想到好的办法处理,如果哪位有思路,还请赐教;如果对于此类序列化与反序列化有好的方法,也请指教!

你可能感兴趣的文章
||PHP||关于=>和->以及::的用法
查看>>
最短路径问题
查看>>
Yii2中定义自己的Widget
查看>>
Aforge.net识别简易数字验证码问题
查看>>
JVM系列二:GC策略&内存申请、对象衰老
查看>>
MySQL 数据库备份策略:全备与增量备份
查看>>
Springboot的热部署
查看>>
Thinking in UML-1-为什么需要UML
查看>>
vs编译obj给delphi用
查看>>
过游戏保护NP或TP的几种方法和思路
查看>>
equals和hashcode为什么要一起重写
查看>>
模态与非模态对话框的问题
查看>>
httpclient 备注 控制连接时间及多线程错误
查看>>
地对地导弹地对地导弹地对地导弹
查看>>
浏览器根对象window之performance
查看>>
让div 充满整个body
查看>>
常用排序算法
查看>>
程序员保持快乐活跃的6个好习惯(转)
查看>>
找工作的一些感悟——前端小菜的成长
查看>>
jSON Call can throw but it is not marked with try
查看>>