C++通用性的Class转化为json。使用boost,tuple完成反射,使用jsoncpp,cmake。

前面写了一个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)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值