C++再优化,80行, class转json,数据结构与算法分离
需求概述,从服务器用protobuf,接受消息,但是本身protobuf本身结构很大,使用自定义class接收protobuf消息,存储,并实现转json。数据结构与算法分离,使用jsoncpp,boost库。
上结果
上代码
main.cpp//测试使用
#include <iostream>
#include "Class_to_Json.h"
int main() {
//test
any_class car1("car", "name", "color", "other_car", "shuzu", "other_car1");//传入6个标签
car1.insert("qqq");//觉得标签不够,再加一个
//为标签赋值,任意类型,测试int, double, string
car1.set("qqq", 561456.54564);
car1.set("car", 1563143568);
car1.set("name", std::string("bie ke"));
car1.set("color", std::string("red"));
//测试添加类
any_class car2("name", std::string("GG"));
car2.set("name", std::string("ka yan"));
car2.set("GG", 564);
//往标签添加一个car2类
car1.set("other_car", car2);
//测试标签数组
std::vector<int> f = {1546,561,51,561,44,14,4,514,584};
car1.set("shuzu", f);
//再测试一个类
any_class car3;
car3.insert("qqq");
car3.set("qqq", 561456.54564);
car1.set("other_car1", car3);
//先调用to_json转化为Json::Value类, 再转化为string
std::string x = car1.to_json().toStyledString();
std::cout << x;
}
Class_to_Json.h
//
// Created by haosir on 19-3-8.
//
#ifndef UNTITLED4_TEST2_H
#define UNTITLED4_TEST2_H
#include <iostream>
#include <map>
#include <boost/any.hpp>
#include <tuple>
#include <typeinfo>
#include <json/json.h>
#include <string>
class any_class{
public:
any_class(){};
template <class... Arg>
any_class(std::string T, Arg... input){
list[T] = NULL;
func(input...);
}
template <class... Arg>
void func(std::string T, Arg... input){
list[T] = NULL;
func(input...);
}
void func(std::string T){
list[T] = NULL;
}
void set(std::string, boost::any );
template <class T>
T get_value(std::string);
Json::Value to_json();
template <class T>
static void add_json(any_class, Json::Value &, std::string );
template <class T>
static void add_json(Json::Value &, std::string, std::vector<T>);
static void add_json(Json::Value &, std::string, any_class);
void insert(std::string);
private:
std::map<std::string, boost::any> list;
};
#endif //UNTITLED4_TEST2_H
Class_to_Json.cpp
//
// Created by haosir on 19-3-8.
//
#include "Class_to_Json.h"
void any_class::set(std::string key, boost::any value){
if(list.find(key) != list.end())
list[key] = value;
else
std::cerr << "no this key :" << key << " please insert.first";
}
void any_class::insert(std::string key){
if(list.find(key) == list.end())
list[key] = NULL;
}
template <class T>
T any_class::get_value(std::string input){
return boost::any_cast<T>(list[input]);
}
Json::Value any_class::to_json(){
Json::Value root;
for(const auto &it : list){
#ifndef MY_CASE
#define CASE1(_TYPE_) if(it.second.type() == typeid(_TYPE_))\
add_json<_TYPE_>(*this, root, it.first);
#define CASE2(_TYPE_) if(it.second.type() == typeid(std::vector<_TYPE_>))\
add_json<_TYPE_>(root, it.first, this->get_value<std::vector<_TYPE_>>(it.first));
#endif
CASE1(int);
CASE1(double);
CASE1(std::string);
CASE2(std::string);
CASE2(int);
if(it.second.type() == typeid(any_class))
add_json(root, it.first, boost::any_cast<any_class>(it.second));
}
return root;
}
template <class T>
void any_class::add_json(any_class a, Json::Value &root, std::string key){
root[key] = a.get_value<T>(key);
}
template <class T>
void any_class::add_json(Json::Value &root, std::string key, std::vector<T> value){
for(const auto &it : value) {
root[key].append(it);
}
}
void any_class::add_json(Json::Value &root, std::string key, any_class input){
root[key] = input.to_json();
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(Class_to_Json)
set(CMAKE_CXX_STANDARD 14)
add_executable(Class_to_Json main.cpp Class_to_Json.h Class_to_Json.cpp)
target_link_libraries(Class_to_Json libjsoncpp.a)