欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++類(lèi)結(jié)構(gòu)體與json相互轉(zhuǎn)換

 更新時(shí)間:2021年09月30日 09:07:39   作者:Yaronzz  
這篇文章主要介紹的是C++類(lèi)結(jié)構(gòu)體與json相互轉(zhuǎn)換,json字符串一般使用的是開(kāi)源的類(lèi)庫(kù)Newtonsoft.Json,方法十分簡(jiǎn)潔,下面就隨小編一起看下面文章內(nèi)容吧

1. 背景與需求

之前寫(xiě)C#的時(shí)候,解析json字符串一般使用的是開(kāi)源的類(lèi)庫(kù)Newtonsoft.Json,方法十分簡(jiǎn)潔,比如:

class Project
{
    public string Input { get; set; }
    public string Output { get; set; }
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
Project test = serializer.Deserialize<Project>(@"{"Input":"1","Output":"2"}");


一行代碼就能將json字符串轉(zhuǎn)為相應(yīng)的類(lèi)對(duì)象。

最近寫(xiě)C++需要處理一下json數(shù)據(jù),于是上github找了很多很強(qiáng)大的開(kāi)源庫(kù),像jsoncpp、rapidjsonjson,基本上都滿足了開(kāi)發(fā)需求,但想要做成像寫(xiě)C#那樣子就要做二次開(kāi)發(fā)。于是有了自己寫(xiě)一個(gè)簡(jiǎn)單的json轉(zhuǎn)類(lèi) | 結(jié)構(gòu)體的工具的想法(開(kāi)源地址)。

需求如下:

  • 只有頭文件,方便使用
  • 最多三行代碼解決轉(zhuǎn)換
  • 支持類(lèi)|結(jié)構(gòu)體 與 json的相互轉(zhuǎn)換
  • 支持多種基本數(shù)據(jù)類(lèi)型,如int、floatstring、bool
  • 支持STL基本類(lèi)型,如vector、list、map<string,T>等
  • 支持嵌套關(guān)系
  • 支持成員重命名,比方說(shuō)json中的關(guān)鍵字是name,成員命名可寫(xiě)成Name或其他。

2. 最終使用的樣例代碼

class Student
{
public:
    string Name;
    int Age;

    AIGC_JSON_HELPER(Name, Age)//成員注冊(cè)
    AIGC_JSON_HELPER_RENAME("name","age")//成員重命名,不需要可以刪除這條
};

int main()
{
    //json轉(zhuǎn)類(lèi)對(duì)象
    Student person;
    JsonHelper::JsonToObject(person, R"({"name":"XiaoMing", "age":15})");
 //類(lèi)對(duì)象轉(zhuǎn)json
    string jsonStr;
    JsonHelper::ObjectToJson(person, jsonStr);
    return 0;
}

3. 實(shí)現(xiàn)方法

因?yàn)閯偤?code>rapidjson只需要頭文件就可以使用,所以選擇了rapidjson作為基礎(chǔ)庫(kù),進(jìn)行二次開(kāi)發(fā)。

3.1 基礎(chǔ)類(lèi)型的轉(zhuǎn)換

作為最底層的接口,只需要進(jìn)行一個(gè)賦值的操作即可,后續(xù)如果想要增加一些其他類(lèi)型支持,添加起來(lái)也比較方便。

static bool JsonToObject(int &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsInt())
        return false;
    obj = jsonValue.GetInt();
    return true;
}

static bool JsonToObject(unsigned int &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsUint())
        return false;
    obj = jsonValue.GetUint();
    return true;
}

static bool JsonToObject(int64_t &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsInt64())
        return false;
    obj = jsonValue.GetInt64();
    return true;
}

//其他類(lèi)型... ...

3.2 類(lèi)成員注冊(cè)

這里使用宏定義方式 + 可變參數(shù)模板的方式來(lái)實(shí)現(xiàn),即可依次對(duì)注冊(cè)的成員進(jìn)行賦值

template <typename TYPE, typename... TYPES>
static bool WriteMembers(std::vector<std::string> &names, int index, rapidjson::Value &jsonValue, TYPE &arg, TYPES &... args)
{
    if (!WriteMembers(names, index, jsonValue, arg))
        return false;
    return WriteMembers(names, ++index, jsonValue, args...);
}

template <typename TYPE>
static bool WriteMembers(std::vector<std::string> &names, int index, rapidjson::Value &jsonValue, TYPE &arg)
{
    const char *key = names[index].c_str();
    if (!jsonValue.HasMember(key))
        return true;

    if (!JsonToObject(arg, jsonValue[key]))
        return false;
    return true;
}
#define AIGC_JSON_HELPER(...)  \
bool AIGC_CONVER_JSON_TO_OBJECT(rapidjson::Value &jsonValue, std::vector<std::string> &names) \
{     \
    if (names.size() <= 0)  \
        names = aigc::JsonHelper::GetMembersNames(#__VA_ARGS__); \
    return aigc::JsonHelper::WriteMembers(names, 0, jsonValue, __VA_ARGS__); \
} 
                                                                                                                                       

3.3 自定義類(lèi)的轉(zhuǎn)換

自定義類(lèi)由于并不清楚外界使用時(shí),是否有按規(guī)定添加好成員注冊(cè)接口,所以這里采用enable_if的方式來(lái)嘗試調(diào)用,編譯的時(shí)候也就不會(huì)報(bào)錯(cuò)。

template <bool, class TYPE = void>
struct enable_if
{
};

template <class TYPE>
struct enable_if<true, TYPE>
{
    typedef TYPE type;
};

template <typename T>
struct HasConverFunction
{
    template <typename TT> static char func(decltype(&TT::AIGC_CONVER_JSON_TO_OBJECT));
    template <typename TT> static int func(...);
    const static bool has = (sizeof(func<T>(NULL)) == sizeof(char));
};

template <typename T, typename enable_if<HasConverFunction<T>::has, int>::type = 0>
static inline bool JsonToObject(T &obj, rapidjson::Value &jsonValue)
{
    std::vector<std::string> names = LoadRenameArray(obj);
    return obj.AIGC_CONVER_JSON_TO_OBJECT(jsonValue, names);
}

template <typename T, typename enable_if<!HasConverFunction<T>::has, int>::type = 0>
static inline bool JsonToObject(T &obj, rapidjson::Value &jsonValue)
{
    return false;
}

3.4 外部調(diào)用接口

/**
 * @brief conver json string to class | struct
 * @param obj : class or struct
 * @param jsonStr : json string 
 */
template <typename T>
static inline bool JsonToObject(T &obj, const std::string &jsonStr)
{
    rapidjson::Document root;
    root.Parse(jsonStr.c_str());
    if (root.IsNull())
        return false;

    return JsonToObject(obj, root);
}

最核心的部分也就上面的幾個(gè)模塊,其他的都是一些瑣碎的增加類(lèi)型支持等操作。

到此這篇關(guān)于C++類(lèi)結(jié)構(gòu)體與json相互轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++類(lèi)結(jié)構(gòu)體與json相互轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在C++中反射調(diào)用.NET的方法(一)

    在C++中反射調(diào)用.NET的方法(一)

    為什么要在C++中調(diào)用.NET呢?接下來(lái)通過(guò)本文給大家介紹在C++中反射調(diào)用.NET的方法(一),需要的朋友參考下吧
    2017-02-02
  • 關(guān)于C++中的static關(guān)鍵字的總結(jié)

    關(guān)于C++中的static關(guān)鍵字的總結(jié)

    C++的static有兩種用法:面向過(guò)程程序設(shè)計(jì)中的static和面向?qū)ο蟪绦蛟O(shè)計(jì)中的static。前者應(yīng)用于普通變量和函數(shù),不涉及類(lèi);后者主要說(shuō)明static在類(lèi)中的作用
    2013-09-09
  • C++實(shí)現(xiàn)分水嶺算法(Watershed Algorithm)

    C++實(shí)現(xiàn)分水嶺算法(Watershed Algorithm)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)分水嶺算法Watershed Algorithm,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一 下
    2018-01-01
  • c++ vector模擬實(shí)現(xiàn)的全過(guò)程

    c++ vector模擬實(shí)現(xiàn)的全過(guò)程

    這篇文章主要給大家介紹了關(guān)于c++ vector的模擬實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Qt 信號(hào)自定義槽函數(shù)的實(shí)現(xiàn)

    Qt 信號(hào)自定義槽函數(shù)的實(shí)現(xiàn)

    Qt中實(shí)現(xiàn)自定義信號(hào)與槽函數(shù),信號(hào)用于發(fā)送并觸發(fā)槽函數(shù),槽函數(shù)則是具體的功能實(shí)現(xiàn),本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)個(gè)人財(cái)務(wù)管理

    C語(yǔ)言實(shí)現(xiàn)個(gè)人財(cái)務(wù)管理

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)個(gè)人財(cái)務(wù)管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能

    C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Atom安裝配置C/C++詳細(xì)教程

    Atom安裝配置C/C++詳細(xì)教程

    Atom (一款開(kāi)源的代碼編輯器)是github專(zhuān)門(mén)為程序員推出的一個(gè)跨平臺(tái)文本編輯器。這篇文章主要介紹了Atom安裝配置C/C++教程,需要的朋友可以參考下
    2020-05-05
  • 從匯編看c++的默認(rèn)析構(gòu)函數(shù)的使用詳解

    從匯編看c++的默認(rèn)析構(gòu)函數(shù)的使用詳解

    本篇文章是對(duì)c++中默認(rèn)析構(gòu)函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • C語(yǔ)言sqrt函數(shù)的實(shí)例用法講解

    C語(yǔ)言sqrt函數(shù)的實(shí)例用法講解

    在本篇文章里小編給大家整理的是關(guān)于C語(yǔ)言sqrt函數(shù)的實(shí)例內(nèi)容以及用法詳解,需要的朋友們可以參考下。
    2020-02-02

最新評(píng)論