赞
踩
最近在搞一个C++项目,用到了json和类的相互转化。但是c++没有反射,也没有像java一个方便的插件,没法办只能自己搞一个了。网上找了一下,发现nlohmann::json不错。已经运用到实际项目代码中,这里记录下。
解压之后,只需要包含 single_include\nlohmann\json.hpp
文件即可
编译时,需要编译器支持c++11。linux中,g++ -std=c++11 ,windows中使用支持c++11的编译器
#include <iostream>
#include "D:\\single_include\\nlohmann\\json.hpp"
using json = nlohmann::json;
using namespace std;
namespace nlohmann {
class videoinfo {
public:
int id;
string name;
};
//json转class用到,需要自定义
//This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators).
void from_json(const json& j, videoinfo& v) {
j.at("id").get_to(v.id);
j.at("name").get_to(v.name);
}
//class转json用到,需要自定义
//This function is usually called by the constructors of the basic_json class.
void to_json(json& j, const videoinfo& value){
j = json{ {"id", value.id}, {"name",value.name} };
}
};
int main()
{
json j = { {"id",3},{"name","jiahui"}};
//json转class
auto x = m.get<nlohmann::videoinfo>();
//class转json
json m = x;
//获取字符串
string str = j.dump();
std::cout << "Hello World!\n";
}
以上只演示了string和class之间的转换,如果需要其他的操作
参考这里:
官网:https://nlohmann.github.io/json/api/basic_json/
中文:https://www.cnblogs.com/linuxAndMcu/p/14503341.html#_label2_5
https://www.cnblogs.com/kezunlin/p/12058300.html
1.如果字符串(json object)初始化json对象,没有得到json的object类型,依然是string。解决方法是初始化时使用迭代器。
比如:
std::string s = "{\"happy\":true,\"pi\":3.141}";
json m = json::parse(s.begin(), s.end());
2.如果定义的类中没有默认构造函数,那么你需要这样实现转换函数(上面的例子有默认构造函数)
namespace nlohmann
{
template <>
struct adl_serializer<nlohmann::videoinfo>
{
static nlohmann::videoinfo from_json(const json& j)
{
return {j.at("id"), j.at("name")};
}
static void to_json(json& j, nlohmann::videoinfo p)
{
j["name"] = p.name;
j["id"] = p.id;
}
};
}
3.当调用json.at()方法时注意,这个方法会抛出异常,需要处理。
4.类继承中如何使用json
class A {
public:
A() : A_name("aaa"), A_age(10) {}
virtual ~A(){}
friend void to_json(nlohmann::json& j, const A e);
friend void from_json(const nlohmann::json& j, A& e);
protected:
//这里的属性权限为protected,应为需要子类给赋值
string A_name;
int A_age;
};
void to_json(nlohmann::json& j, const A e)
{
j = nlohmann::json{
{"A_name", e.A_name},
{"A_age", e.A_age}
};
}
void from_json(const nlohmann::json& j, A& e)
{
j.at("A_name").get_to(e.A_name);
j.at("A_age").get_to(e.A_age);
}
class B : public A
{
public:
B() :B_address("b_address") {}
virtual ~B() {}
friend void to_json(nlohmann::json& j, const B& e);
friend void from_json(const nlohmann::json& j, B& e);
private:
string B_address;
};
void to_json(nlohmann::json& j, const B& e)
{
j = static_cast<A>(e);
j["B_address"] = e.B_address;
}
void from_json(const nlohmann::json& j, B& e)
{
from_json(j, static_cast<A&>(e));
j.at("B_address").get_to(e.B_address);
}
int main()
{
string str = "{\"A_age\":3333,\"A_name\":\"1111\",\"B_address\":\"xxxx\"}";
nlohmann::json dataJ = nlohmann::json::parse(str);
B x;
from_json(dataJ, x);
B b;
nlohmann::json j = b;
cout << j.dump() << endl;
}
5.编码问题
本库只支持utf-8编码格式,其他格式会报异常。
怎么处理编码转换,参考这里
6.如果你的数据结构很复杂,建议参考使用这个扩展,反射功能,无需再手动写from_json
和to_json
7.如果你的类字段为基础类型,那么可以使用库提供的注册宏,不需要自定义两个序列化函数。
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, …)
将在要为其创建代码的类/结构的命名空间内定义。
NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, …)
将在要为其创建代码的类/结构中定义。 该宏还可以访问私有成员。
举例:
class A {
public:
A() : A_name("aaa"), A_age(10) {}
virtual ~A(){}
NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, A_name, A_age);
protected:
//这里的属性权限为protected,应为需要子类给赋值
string A_name;
int A_age;
};
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。