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

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. 接下来要解决的问题

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

C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化的更多相关文章

  1. C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化

    在前两篇文章中,我们已经完成对普通对象以及复杂对象嵌套的序列化与反序列化,见如下地址: C++对象的JSON序列化与反序列化探索 C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化 ...

  2. json相关类库,java对象与json相互转换

    有效选择七个关于Java的JSON开源类库 转自:http://www.open-open.com/lib/view/open1397870197828.html 翻译: (英语原文:http://w ...

  3. jackson json转对象 对象转json

    一,Jackson使用示例 第1步:创建ObjectMapper对象. 创建ObjectMapper对象.它是一个可重复使用的对象. ObjectMapper mapper = new ObjectM ...

  4. fastjson,对象转json字符串的过程中对value为null的值的一些处理

    前言 fastjson是一个非常好用的java库,用于操作对象json序列化等等. 问题 最近在写代码的时候遇到问题,通过JSON.toJSONString方法将一个实体对象转为json字符串,转出来 ...

  5. java对象与Json字符串之间的转化(fastjson)

    1. 首先引入jar包 在pom.xml文件里加入下面依赖: <dependency> <groupId>com.alibaba</groupId> <art ...

  6. java对象与Json字符串之间的转化

    public class Test { public static void main(String[] args) { // 实现java对象与Json字符串之间的转化 // 1. Person对象 ...

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

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 一:背景 作为一名C++开发人员,我始终很期待能够像C#与JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找 ...

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

    一:背景 作为一名C++开发人员,我一直很期待能够像C#与JAVA那样,可以轻松的进行对象的序列化与反序列化,但到目前为止,尚未找到相对完美的解决方案. 本文旨在抛砖引玉,期待有更好的解决方案:同时向 ...

  9. 转载C# 对象转Json序列化

    转载原地址:  http://www.cnblogs.com/plokmju/p/ObjectByJson.html JSON Json(JavaScript Object Notation) 是一种 ...

随机推荐

  1. TOJ 4325 RMQ with Shifts / 线段树单点更新

    RMQ with Shifts 时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte 描述 In the traditional RMQ (Range M ...

  2. mysql并发复制系列 一:binlog组提交

    http://blog.itpub.net/28218939/viewspace-1975809/ 作者:沃趣科技MySQL数据库工程师  麻鹏飞 MySQL  Binary log在MySQL 5. ...

  3. the railway problem(the example of stack)

    this problem is a very classic problem which can use stack to solve. the problem can be searched thr ...

  4. windows快捷操作

    命令行启动或关闭VMWare服务: net start VMwareHostdVMAuthdServiceVMUSBArbService"VMware NAT Service"VM ...

  5. apache vhost 访问权限配置

    apache的<directory>     </directory>语句,查考如下: 如何访问根目录下的目录http://192.168.1.12/test/ 第一.缺省ap ...

  6. debian root用户在shell下如何能够使用颜色

    转载:http://hi.baidu.com/aivera/item/f31c4a590ef72609e6c4a596 编辑 /root/.bashrc 这个文件, 把里面这几行前面的#号去掉就可以了 ...

  7. SMI接口,SMI帧结构,MDC/MDIO

    转载:http://blog.csdn.net/zyboy2000/article/details/7442464 SMI全称是串行管理接口(Serial Management Interface). ...

  8. Java中执行外部命令

    在项目中执行一个linux的shell脚本,于是需要在java环境下执行外部命令如系统命令.linux命令的需求,本人小小研究了一下,又上网查了一些资料先整理如下. java执行外部命令主要依赖两个类 ...

  9. CSS code snip enjoy.

    <!-- information-total得是动态获取吧. --> <div class="information-mod"> <div class ...

  10. customerized convert from field type to DB field's type

    @LastModifiedDate @Convert(converter = LocalDateTime2TimestampConverter.class) @Slf4j public class L ...