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

新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

    一:背景

    作为一名C++开发人员,我始终很期待能够像C#JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找到相对完美的处理方案。

    本文旨在抛砖引玉,期待有更好的处理方案;同时向大家追求帮助,处理本文中未处理的问题。 

    二:相干技术介绍

    本方案采取JsonCpp来做具体的JSON的读入与输出,再结合类成员变量的映射,终究实现对象的JSON序列化与反序列化。

    本文不再探讨如何使用JsonCpp,此处将作者在应用时发现的两处问题进行说明:

    1.       下载Jsoncpp,编译其lib,并且引用到项目中,发现有如下错误:

    错误1       fatal error C1083: Cannot open compiler generated file: '../../build/vs71/release/lib_json\json_writer.asm': No such file or directory       c:\Documents and Settings\Administrator\jsoncpp-src-0.6.0-rc2\jsoncpp-src-0.6.0-rc2\src\lib_json\json_writer.cpp

    错误2       fatal error LNK1257: 代码生成失败     JasonSerialize 

     

     可以通过在修改LIB库项目的属性处理,如下图[关闭汇编输出]

    序列化和对象

    2.      JSONCPP官网首页的下载版本是0.5.0,此版本不支撑Int64等类型,下载版本jsoncpp-src-0.6.0-rc2后便可支撑. 

    三:一个基于JsonCpp的序列化与反序列化基类

    先看代码:

#pragma once
#include <string>
#include <vector>
#include "json/json.h"
using std::string;
using std::vector;
struct CJsonObejectBase
{
protected:enum CEnumJsonTypeMap{asInt = 1,asUInt,asString,asInt64,asUInt64,};
public:CJsonObejectBase(void){}
public:virtual ~CJsonObejectBase(void){}string Serialize(){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 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;}		}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)){  int nSize = m_listName.size();for (int i=0; i < nSize; ++i ){void* pAddr = m_listPropertyAddr[i];switch(m_listType[i]){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;}return false;}
protected: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;vector<string> m_listName;vector<void*>  m_listPropertyAddr;vector<CEnumJsonTypeMap>	   m_listType;
};
每日一道理
爱,有的时候不须要山盟海誓的承诺,但她一定须要细致入微的关怀与问候;爱,有的时候不须要梁祝化蝶的悲壮,但她一定须要心有灵犀的默契与投合;爱,有的时候不须要雄飞雌从的追随,但她一定须要相濡以沫的支撑与理解。

    此类主要有三个函数:Serialize、DeSerialize及 SetPropertys、SetProperty,其中前两个函数主要是用来实现对象的序列化与反序列化;SetPropertys是一个纯虚函数,如果一个类须要具备序列化功能,只须要从此类继承,同时调用SetProperty函数,将各个字段的属性进行设置便可。  

    四:使用对象的序列化及反序列化功能

    要使对象具体相应功能,须要继承上述的基类,如下: 

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

    继承后,我们可以使用如下代码来进行测试

    序列化: 

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

    结果:

    序列化和对象

    反序列化: 

void CJasonSerializeDlg::OnBnClickedOk2()
{const char* pstr = "{\"MsgContent\":\"哈哈22\",\"MsgID\":11111111111111111,\"MsgTitle\":\"黑黑22\"}";CTestStruct stru;stru.DeSerialize(pstr);CString strShow = "";strShow.Format("MsgID:%I64u\r\nMsgTile:%s\r\nMsgContent:%s", stru.MsgID, stru.MsgTitle.c_str(), stru.MsgContent.c_str());AfxMessageBox(strShow);
}

    结果:

    序列化和对象 

    五:未处理的问题

    1.       现在我对属性的映射采取的是vector次序映射的方式,这样必需在子类中对每个属性进行设置,是不是有宏的策略可以使这部分工作更加省力?

    2.       现在只支撑整型、64位整型及字符串类型,须要支撑其他类型,可以在基类中添加映射便可。

    3.       现在只支撑单个简略对象[其属性均为简略类型]的序列化与反序列化,暂时未斟酌如何支撑复杂的,如外部包括其他的复杂对象、包括数组等情况。 

    完整代码请于如下链接下载:

     http://download.csdn.net/detail/tragicguy/5630473

文章结束给大家分享下程序员的一些笑话语录: 程序员的愿望
  有一天一个程序员见到了上帝.上帝: 小伙子,我可以满足你一个愿望.程序员: 我希望中国国家队能再次打进世界杯.
  上帝: 这个啊!这个不好办啊,你还说下一个吧!
  程序员: 那好!我的下一个愿望是每天都能休息6个小时以上.
  上帝: 还是让中国国家打进世界杯.

--------------------------------- 原创文章 By
序列化和对象
---------------------------------

转载于:https://www.cnblogs.com/xinyuyuanm/p/3150403.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netflix监管者测试–引入了知事-Junit-runner

考虑一个典型的Netflix Governator junit测试。 public class SampleWithGovernatorJunitSupportTest {Rulepublic LifecycleTester tester new LifecycleTester();Testpublic void testExampleBeanInjection() throws Exception {tester.start();Injector injector tester.…

python socket udp并发_Python进阶----UDP协议使用socket通信,socketserver模块实现并发

Python进阶----UDP协议使用socket通信,socketserver模块实现并发一丶基于UDP协议的socket实现UDP协议传输数据代码如下:&#x1f447;### 客户端# -*-coding:utf-8-*-# Author:Dsimport socket# 实例化UDP协议的socket对象 ,配置参数, socket.SOCK_DGRAM(数据报)udp_clisocket.…

c++ 使用vs2010调用 win32api

以前读书时都是用vc6.0.后来学c#用vs。装系统只装了vs2010.今天用vs2010写c程序。发现有点陌生。就总结下&#xff0c;免得以后忘记。 首先用vs2010选择c语言。新建一个win32控制台程序。项目打开后会发现stdafx.h&#xff0c;targetver.h&#xff0c;stdafx.cpp还有自己的winA…

Java IO基准测试:Quasar与异步ForkJoinPool与ManagedBlock

“ Arien看到了我们运行的parallelStreams和ForkJoin基准测试的结果后&#xff0c;在Twitter上与我们联系。 这激起了他的兴趣&#xff0c;因此他进行了一些自己的测试&#xff0c;将Quasar纤维加入了混合物。 这是他的结果和结论。” –塔基皮&#xff08;Takipi&#xff09;A…

WP8开发札记(一)WP8应用生命周期管理

在介绍生命周期前&#xff0c;我们先了解两个相关的概念。 1、墓碑机制&#xff1a;WP8与Android采用的真后台机制不同&#xff0c;WP8采用的是墓碑机制。一旦从当前应用程序离开&#xff08;非退出&#xff09;&#xff0c;该应用会被墓碑化&#xff0c;这样可以更好的管理&am…

python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...

第8.3节Python类的__init__方法深入剖析&#xff1a;构造方法与继承详解一、 引言上两节介绍了构造方法的语法及参数&#xff0c;说明了构造方法是Python的类创建实例后首先执行的方法&#xff0c;并说明如果类没有重写构造方法&#xff0c;Python将会给出默认的__init__方法…

OpenShift DIY:使用Gradle构建Spring Boot / Undertow应用程序

由于此bug&#xff0c; Gradle 1.6是在OpenShift上运行的最后一个受支持的Gradle版本。 但是从Gradle 2.2开始&#xff0c;这不再是问题&#xff0c;因此使用自己动手做墨盒在OpenShift上运行最新的Gradle不再是问题。 DIY墨盒是一种实验性墨盒&#xff0c;它提供了一种在OpenS…

P2P编程(十)

此为网络编程的一个系列&#xff0c;后续会把内容补上。。。。 转载于:https://www.cnblogs.com/liangjie/p/3155866.html

python默认数据转换_Python_数据类型转换

数据类型转换int(x [,base ]) 将x转换为一个整数long(x [,base ]) 将x转换为一个长整数float(x ) 将x转换到一个浮点数complex(real [,imag ]) 创建一个复数str(x ) 将对象 x 转换为字符串repr(x ) 将对象 x 转换为表达式字符串eval(str ) 用来计算在字符串中的有效Python表达式…

Gradle入门:创建Web应用程序项目

这篇博客文章描述了如何使用Gradle创建一个Web应用程序项目。 更具体地说&#xff0c;我们想创建一个使用Java的Web应用程序项目&#xff0c;将我们的Web应用程序打包到WAR文件中&#xff0c;并在开发环境中运行我们的Web应用程序。 让我们找出如何满足这些要求。 补充阅读&…

js编码java解码_Js编码和Java后台解码

注&#xff1a;在使用get提交&#xff0c;url传递参数的时候&#xff0c;会带来中文乱码的问题&#xff0c;对此可以使用js编码来解决。Js编码的几种方式区别&#xff1a;1.window.escape()与HttpUtility.UrlEncodeUnicode()编码格式一样&#xff1a;将一个汉字编码为%uxxxx格式…

使用JAX-RS和Jetty创建Web服务和Rest Server

用Java创建WebService非常容易。 将其添加到ServletContainer并将其部署到嵌入式WebServer仅需要几行代码。 让我们创建一个具有两个函数的简单计算器&#xff0c;作为WebService的示例。 计算器将计算任何数量的squareRoot和平方。 它将返回一个简单的JSON响应&#xff0c;其…

java填充二维数组_Java用Arrays.fill()初始化二维数组的实现

在最短路径问题上遇到了一个问题&#xff0c;对于二维int数组 map[][],需要初始化为int的最大值&#xff0c;不想用双重循环赋初值&#xff0c;想用Arrays.fill()填充但是失败了。。。。。。首先说明&#xff0c;Arrays.fill()并不能提高赋值的效率&#xff0c;在函数的内部也是…

maya 中使用节点连接来求余数:

绑个东西要用到求余&#xff0c;不喜欢用表达式&#xff0c;就想用节点连出来&#xff0c;找了下网上只有 镀金铆钉 在火星时代上的教程&#xff0c;不过不能下载了&#xff0c;就自己想了下&#xff0c;终于搞出来了&#xff0c;做下笔记&#xff0c;不要忘了。 求余的思路&a…

Java8多线程ForkJoinPool:处理异常

引入Java8 lambda背后的主要动机之一是能够尽可能轻松地使用多核的能力&#xff08;请参阅精通Lambdas&#xff1a;多核世界中的Java编程 &#xff09;。 只需将代码从collection.stream()...更改为collection.parallelStream()...您就可以使用即时多线程&#xff0c;从而为您的…

java web 登录界面案例_【JavaWeb】74:写一个登录案例

今天是刘小爱自学Java的第74天。感谢你的观看&#xff0c;谢谢你。话不多说&#xff0c;开始今天的学习&#xff1a;Java又常被称之为后台开发。什么叫后台呢&#xff1f;除了后台还有什么前台、前端后端……这些概念一大堆&#xff0c;还容易弄混。以一个三层架构的知识点来引…

7种JIRA集成可优化Java开发流程

有哪些最佳集成可以用来优化JIRA工作流程&#xff1f; 我喜欢寻找在工作流程中提高效率的方法。 看着那些小的自动化和流畅的流程&#xff0c;使我的脸上露出笑容。 我知道我并不孤单&#xff0c;偶尔花更多的时间来获得一点点提升以使其正常工作&#xff0c;而不是最终节省了我…

hive处理日志,自定义inputformat

开放环境&#xff0c;hadoop-0.20.2&#xff0c;hive-0.6 1.日志分隔符 Xml代码 2010-05-31 10:50:17|||61.132.4.82|||http://www.360buy.com/product/201185.html 2010-05-31 10:50:17|||61.132.4.82|||http://www.360buy.com/product/201185.html分隔符是“ ||| ”&#xf…

java 封箱_java封箱和拆箱分析

学习java肯定会涉及到“封箱”和“拆箱”&#xff0c;那么什么是“封箱”和“拆箱呢&#xff1f;我相信有不少的老师或者作者都对此做过总结&#xff0c;在这里就不详细说了。总的来说就是&#xff1a;装箱就是自动将基本数据类型转换为包装器类型&#xff1b;拆箱就是自动将包…

EE JSP:使用自定义标签库生成动态内容

在Web应用程序中开发View层时&#xff0c;您希望尽量不要重复JSP文件中的内容。 JSP spec API允许您通过使用标记库来减少这种重复。 定制JSP标记是用户定义的xml标记元素&#xff0c;您可以将其插入JSP文件以替换为某些动态内容。 这是一个使用自定义JSP标记的简单jsp示例 &a…