前面写了一个Class转json的文章,太特殊了,维护和其他都很难。。。
现在这个我想了几天,终于写了一个较通用的版本的。
先上结果
直接上代码
README.md
Created by Haosir on 2019/3/1.
必须的库:boost和jsoncpp库,安装在usr/local/include下,/usr/local/lib64/libjsoncpp.a。
实现说明:
使用boost::any和tuple实现函数字符串到变量名的映射。
Needs_file是保存tuple绑定的文件
tuple保存变量和变量名的映射关系。
to_json()这个函数是对类型进行分析,然后进行赋值。
如果是自定义类型,本文中的person,则调用字类型的to_json()。
通用性:
在往类中添加变量的时候,只需要添加 set_your_var 和私有变量就可以。如果添加自定义类,则需要自定义类有to_json()函数。
to_json.h
//
// Created by huanghao on 2019/2/27.
//
#ifndef CLASS_TO_JSON_TO_JSON_H
#define CLASS_TO_JSON_TO_JSON_H
#include <iostream>
#include <vector>
#include <boost/any.hpp>
#include <tuple>
#include <typeinfo>
#include <json/json.h>
class person{
public:
person(){};
person(const person &);
std::string get_name(){ return name; }
int64_t get_phone(){ return phone; }
void name_set(std::string );
void phone_set(int64_t );
static Json::Value to_json(person);
private:
std::string name;
int64_t phone;
std::vector<std::tuple<boost::any, std::string>> Needs_file;
};
class school{
public:
school(){};
school(std::string, double, int64_t, person, person, std::vector<int>);
static Json::Value to_json(school);
void name_set(std::string);
void id_set(double);
void eamil_set(int64_t);
void one_set(person);
void two_set(person);
void others_set(std::vector<int>);
void others_push_back(int);
private:
std::string name;
double id;
int64_t eamil;
person one;
person two;
std::vector<int> others;
std::vector<std::tuple<boost::any, std::string>> Needs_file;
};
#endif //CLASS_TO_JSON_TO_JSON_H
school.cpp
//
// Created by Haosir on 2019/3/1.
//
#include "to_json.h"
school::school(std::string name, double id, int64_t eamil, person one, person two, std::vector<int> others)
:name(name), id(id), eamil(eamil), one(one), two(two), others(others) {
Needs_file.emplace_back(std::make_tuple(boost::any(this->name), std::string("name")));
Needs_file.emplace_back(std::make_tuple(boost::any(this->id), std::string("id")));
Needs_file.emplace_back(std::make_tuple(boost::any(this->eamil), std::string("eamil")));
Needs_file.emplace_back(std::make_tuple(boost::any(this->one), std::string("one")));
Needs_file.emplace_back(std::make_tuple(boost::any(this->two), std::string("two")));
Needs_file.emplace_back(std::make_tuple(boost::any(this->others), std::string("others")));
};
void school::name_set(std::string input){
name = input;
Needs_file.emplace_back(std::make_tuple(boost::any(name), std::string("name")));
}
void school::id_set(double input){
id = input;
Needs_file.emplace_back(std::make_tuple(boost::any(id), std::string("id")));
}
void school::eamil_set(int64_t input){
eamil = input;
Needs_file.emplace_back(std::make_tuple(boost::any(eamil), std::string("eamil")));
}
void school::one_set(person input){
one = input;
Needs_file.emplace_back(std::make_tuple(boost::any(one), std::string("person")));
}
void school::two_set(person input){
two = input;
Needs_file.emplace_back(std::make_tuple(boost::any(two), std::string("person")));
}
void school::others_set(std::vector<int> input){
others.assign(input.begin(), input.end());
Needs_file.emplace_back(std::make_tuple(boost::any(others), std::string("others")));
}
void school::others_push_back(int input){
others.push_back(input);
Needs_file.emplace_back(std::make_tuple(boost::any(others), std::string("others")));
}
Json::Value school::to_json(school input){
Json::Value root;
for(auto it : input.Needs_file){
if(std::get<0>(it).type() == typeid(int64_t))
root[std::get<1>(it)] = boost::any_cast<int64_t>(std::get<0>(it));
if(std::get<0>(it).type() == typeid(double))
root[std::get<1>(it)]= boost::any_cast<double>(std::get<0>(it));
if(std::get<0>(it).type() == typeid(std::string))
root[std::get<1>(it)] = boost::any_cast<std::string>(std::get<0>(it));
if(std::get<0>(it).type() == typeid(person))
root[std::get<1>(it)] = person::to_json(boost::any_cast<person>(std::get<0>(it)));
if(std::get<0>(it).type() == typeid(std::vector<int>)) {
if(boost::any_cast<std::vector<int> >(std::get<0>(it)).size() == 0)
root[std::get<1>(it)] = Json::nullValue;
else
for (auto its : boost::any_cast<std::vector<int> >(std::get<0>(it)))
root[std::get<1>(it)].append(its);
}
}
return root;
}
person.cpp
//
// Created by huanghao on 2019/3/1.
//
#include "to_json.h"
person::person(const person &input){
name = input.name;
phone = input.phone;
Needs_file.emplace_back(std::make_tuple(boost::any(name), std::string("name")));
Needs_file.emplace_back(std::make_tuple(boost::any(phone), std::string("phone")));
}
void person::name_set(std::string input){
name = input;
Needs_file.emplace_back(std::make_tuple(boost::any(name), std::string("name")));
}
void person::phone_set(int64_t input){
phone = input;
Needs_file.emplace_back(std::make_tuple(boost::any(phone), std::string("phone")));
}
Json::Value person::to_json(person input){
Json::Value root;
for(auto it : input.Needs_file){
if(std::get<0>(it).type() == typeid(int64_t))
root[std::get<1>(it)] = boost::any_cast<int64_t>(std::get<0>(it));
if(std::get<0>(it).type() == typeid(double))
root[std::get<1>(it)]= boost::any_cast<double>(std::get<0>(it));
if(std::get<0>(it).type() == typeid(std::string))
root[std::get<1>(it)] = boost::any_cast<std::string>(std::get<0>(it));
}
return root;
}
//主函数是测试函数
main.cpp
#include <iostream>
#include <fstream>
#include "to_json.h"
int main()
{
std::cout << "test 1:" << std::endl;
std::vector<int> x {145,14,4136,436,436,4};
school a;
a.name_set("asdasda");
a.eamil_set(435643654);
a.others_set(x);
person b;
b.name_set("asdasd");
b.phone_set(541343584);
a.one_set(b);
std::cout << school::to_json(a) << std::endl;
std::cout << "test 2:" << std::endl;
school test("asdasd", 146581.468, 1531351, person(b), person(b), std::vector<int>());
std::cout << school::to_json(test) << std::endl;
std::ofstream file ("test2.json", std::ios::out);
file << school::to_json(test);
file.close();
}
CMakeList.txt
cmake_minimum_required(VERSION 3.13)
project(Class_to_json)
set(INC_DIR /usr/local/include)
set(LINK_DIR /usr/local/lib64/libjsoncpp.a)
include_directories(${INC_DIR})
link_directories(${LINK_DIR})
link_libraries(libjsoncpp.a)
set(CMAKE_CXX_STANDARD 14)
add_executable(Class_to_json main.cpp to_json.h school.cpp person.cpp)
target_link_libraries(Class_to_json libjsoncpp.a)