背景:
在项目里经常遇到对象和json字符串的相互转换这类问题,在大多数程序里,一般这个问题都比较有比较好的解决方法,往往一个函数搞定。但是到了c++这边却需要我们手撸json库一个一个字段初始化/序列化。如果这时候有一个函数 可以一行代码 unmarshal /marshal 对象岂不是很方便?本文以jsoncpp库为基础,设计这样一个可以支持这种功能的函数,下面进入正题~
设计思路
以unmarshal 为例,我们最终的函数是打造两个这样的模板函数 :
一个从string 的josn直接反序列化对象,一个从jsoncpp库的json对象,反序列化对象。
template<typename T> bool Unmarshal(T& obj,const string& json_str);
template<typename T> bool Unmarshal(T& obj,const Json::Value& json_obj_root);
由于json是具有自递归结构的,所以在设计时,应该也是以递归的方式解决复杂的组合类,我们可以简单的把程序中的变量分为下面几类:

这样我们只需要把这几个场景的 Unmarshal实现了,整体的Unmarshal也就实现了。模板设计的类图应该和我们的分类相对应:

在实现中要注意以下几点:
1、每个分类的Unmarshal模板具有排他性,也就是说基本类型在编译期间只能匹配解析基本类型的模板
2、由于1的保证和这些模板函数名称都是Unmarshal,所以他们之间可以相互嵌套调用对方。
3、指针、和原生数组会涉及到空间分配和长度检测会使得情况变得复杂,本次设计支持的范围不包含对指针、原生数组的支持。
匹配基本类型的Unmarshal模板
//只能解析基本类型 int long bool float double string 的一组模板
/*
* 其实可声明为重载函数,声明为模板只是为了可以放在头文件中
* 不能声明为 template <typename T> bool Unmarshal(int& obj,const Json::Value &root);是因为
* 在编译时编译器不能推断出T的类型,导致编译失败.所以将模板类型列表设置为template <int = 0> (Nontype
* Parameters) 此处int并无实际意义
*/
template <int = 0>
inline bool Unmarshal(int& obj,const Json::Value &root){
if(!root.isIntegral())
return false;
obj = root.asInt();
return true;
}
template <int = 0>
inline bool Unmarshal(long& obj,const Json::Value &root)
.....
匹配stl容器/其他第三方类库的Unmarshal模板
//只能匹配 vector<T> map<string,T> map<long,T> map<int,T> 的一组模板
//vector
template <

本文介绍了一种基于jsoncpp库的C++轻量级对象JSON序列化实现方法,通过模板函数处理基本类型、STL容器和其他自定义struct/class的序列化。文章详细阐述了设计思路、匹配模板及注意事项,并提供了实现代码示例。
最低0.47元/天 解锁文章
2077





