C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化

来源:互联网 发布:mysql启动错误1067 编辑:程序博客网 时间:2024/05/29 14:26

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

C++对象的JSON序列化与反序列化探索

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

1. 序列化基类

#pragma once#include <string>#include <vector>#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<string> m_listName;vector<void*>  m_listPropertyAddr;vector<CEnumJsonTypeMap>   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. 接下来要解决的问题

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


原创粉丝点击