最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用C++17實現(xiàn)JSON庫設計思路示例全解

 更新時間:2023年08月10日 10:09:44   作者:zhoutk  
這篇文章主要為大家介紹了使用C++17實現(xiàn)JSON庫設計思路示例全解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

介紹

從node.js轉(zhuǎn)到c++,特別懷念在js中使用json那種暢快感。在c++中也使用過了些庫,但提供的接口使用方式,總不是習慣,很煩鎖,接口函數(shù)太多,不直觀。參考了很多庫,如:rapidjson, cJson, CJsonObject, drleq-cppjson, json11等,受cJson的數(shù)據(jù)結(jié)構(gòu)啟發(fā)很大,決定用C++手擼一個。

最后因為數(shù)據(jù)存儲需要不區(qū)分型別,又要能知道其型別,所以選擇了C++17才支持的std::variant以及std::any,最終,C++版本定格在c++17,本庫設計為單頭文件,且不依賴c++標準庫以外的任何庫。

項目名稱說明

本人姓名拼音第一個字母z加上josn,即得本項目名稱zjson,沒有其它任何意義。我將編寫一系列以z開頭的相關(guān)項目,命名是個很麻煩的事,因此采用了這種簡單粗暴的方式。

設計思路

簡單的接口函數(shù)、簡單的使用方法、靈活的數(shù)據(jù)結(jié)構(gòu)、盡量支持鏈式操作。使用模板技術(shù),使用給Json對象增加值的方法只有兩個,AddValueBase和AddValueJson。采用鏈表結(jié)構(gòu)(向cJSON致敬)來存儲Json對象,請看我下面的數(shù)據(jù)結(jié)構(gòu)設計,表頭與后面的結(jié)點,都用使用一致的結(jié)構(gòu),這使得在索引操作([])時,可以進行鏈式操作。

項目進度

項目目前完成一半,可以新建Json對象,增加數(shù)據(jù),按key(Object類型)或索引(Array類型)提取相應的值或子對象,生成json字符串。
已經(jīng)做過內(nèi)存泄漏測試,析構(gòu)函數(shù)能正確運行,百萬級別生成與銷毀未見內(nèi)存明顯增長。
任務列表:

  • [x] 構(gòu)造函數(shù)、復制構(gòu)造函數(shù)、析構(gòu)函數(shù)
  • [x] AddValueBase(為Json對象增加值類型)、AddValueJson(為Json對象增加對象類型)
  • [x] operator=、operator[]
  • [x] toString(生成json字符串)
  • [x] toInt、toDouble、toFalse 等值類型轉(zhuǎn)換
  • [x] isError、isNull、isArray 等節(jié)點類型判斷
  • [ ] parse, 從json字符串生成Json對象;相應的構(gòu)造函數(shù)
  • [ ] Extend Json - 擴展對象
  • [ ] Remove[All] key - 刪除數(shù)據(jù), 因為Json對象允許重復的key
  • [ ] findAll - 查找全部, 因為Json對象允許重復的key
  • [ ] std::move語義

數(shù)據(jù)結(jié)構(gòu)

Json 節(jié)點類型定義

(內(nèi)部使用,數(shù)據(jù)類型只在Json類內(nèi)部使用)

enum Type {
    Error,                //錯誤,查找無果,這是一個無效Json對象
    False,                //Json值類型 - false
    True,                 //Json值類型 - true
    Null,                 //Json值類型 - null
    Number,               //Json值類型 - 數(shù)字,庫中以double類型存儲
    String,               //Json值類型 - 字符串
    Object,               //Json類對象類型 - 這是Object嵌套,對象型中只有child需要關(guān)注
    Array                 //Json類對象類型 - 這是Array嵌套,對象型中只有child需要關(guān)注
};

Json 節(jié)點定義

class Json {
    Json* brother;       //與cJSON中的next對應,值類型才有效,指向并列的數(shù)據(jù),但有可能是值類型,也有可能是對象類型
    Json* child;         //孩子節(jié)點,對象類型才有效
    Type type;           //節(jié)點類型
    std::variant <int, bool, double, string> data;   //節(jié)點數(shù)據(jù)
    string name;         //節(jié)點的key
}

接口說明

公開的對象類型,json只支持Object與Array兩種對象,與內(nèi)部類型對應(公開類型)。

enum class JsonType
{
    Object = 6,
    Array = 7
};

接口列表

  • Json(JsonType type = JsonType::Object) //默認構(gòu)造函數(shù),生成Object或Array類型的Json對象
  • Json(const Json& origin) //復制構(gòu)造函數(shù)
  • Json& operator = (const Json& origin) //賦值操作
  • Json operator[](const int& index) //Json數(shù)組對象元素查詢
  • Json operator[](const string& key) //Json Object 對象按key查詢
  • bool AddValueJson(Json& obj) //增加子Json類對象類型, 只面向Array
  • bool AddValueJson(string name, Json& obj) //增加子Json類對象類型,當obj為Array時,name會被忽略
  • template<typename T> bool AddValueBase(T value) //增加值對象類型,只面向Array
  • template<typename T> bool AddValueBase(string name, T value) //增加值對象類型,當this為Array時,name會被忽略
  • string toString() //Json對象序列化為字符串
  • bool isError() //無效Json對象判定
  • bool isNull() //null值判定
  • bool isObject() //Object對象判定
  • bool isArray() //Array對象判定
  • bool isNumber() //number值判定,Json內(nèi)使用double型別存儲number值
  • bool isTrue() //true值判定
  • bool isFalse() //false值判定
  • int toInt() //值對象轉(zhuǎn)為int
  • float toFloat() //值對象轉(zhuǎn)為float
  • double toDouble() //值對象轉(zhuǎn)為double
  • bool toBool() //值對象轉(zhuǎn)為bool

編程示例

簡單使用示例

Json ajson(JsonType::Object);                   //新建Object對象,輸入?yún)?shù)可以省略
    std::string data = "kevin";                     
    ajson.AddValueBase("fail", false);              //增加false值對象
    ajson.AddValueBase("name", data);               //增加字符串值對象
    ajson.AddValueBase("school-en", "the 85th.");   
    ajson.AddValueBase("age", 10);                  //增加number值對象,此處為整數(shù)
    ajson.AddValueBase("scores", 95.98);            //增加number值對象,此處為浮點數(shù),還支持long,long long
    ajson.AddValueBase("nullkey", nullptr);         //增加null值對象,需要送入nullptr, NULL會被認為是整數(shù)0
    Json sub;                                       //新建Object對象
    sub.AddValueBase("math", 99);                 
    ajson.AddValueJson("subJson", sub);             //為ajson增加子Json類型對象,完成嵌套需要
    Json subArray(JsonType::Array);                 //新建Array對象,輸入?yún)?shù)不可省略
    subArray.AddValueBase("I'm the first one.");    //增加Array對象的字符串值子對象
    subArray.AddValueBase("two", 2);                //增加Array對象的number值子對象,第一個參數(shù)會被忽略
    Json sub2;                            
    sub2.AddValueBase("sb2", 222);
    subArray.AddValueJson("subObj", sub2);          //為Array對象增加Object類子對象,完成嵌套需求
    ajson.AddValueJson("array", subArray);          //為ajson增加Array對象,且這個Array對象本身就是一個嵌套結(jié)構(gòu)
    std::cout << "ajson's string is : " << ajson.toString() << std::endl;    //輸出ajson對象序列化后的字符串, 結(jié)果見下方
    string name = ajson["name"].toString();         //提取key為name的字符串值,結(jié)果為:kevin
    int oper = ajson["sb2"].toInt();                //提取嵌套深層結(jié)構(gòu)中的key為sb2的整數(shù)值,結(jié)果為:222
    Json operArr = ajson["array"];                  //提取key為array的數(shù)組對象
    string first = ajson["array"][0].toString();    //提取key為array的數(shù)組對象的序號為0的值,結(jié)果為:I'm the first one.

ajson序列化后結(jié)果為:

{
    "fail": false,
    "name": "kevin",
    "school-en": "the 85th.",
    "age": 10,
    "scores": 95.98,
    "nullkey": null,
    "subJson": {
        "math": 99
    },
    "array": [
        "I'm the first one.",
        2,
        {
            "sb2": 222
        }
    ]
}

詳情請參看demo.cpp或tests目錄下的測試用例

項目地址

https://gitee.com/zhoutk/zjson

https://github.com/zhoutk/zjson

運行方法

該項目在vs2019, gcc7.5, clang12.0下均編譯運行正常。

git clone https://github.com/zhoutk/zjson
cd zjson
cmake -Bbuild .
---windows
cd build && cmake --build .
---linux & mac
cd build && make
run zjson or ctest

后續(xù)會有一系列相關(guān)項目出爐,更多關(guān)于C++17實現(xiàn)JSON庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++如何通過ostringstream實現(xiàn)任意類型轉(zhuǎn)string

    C++如何通過ostringstream實現(xiàn)任意類型轉(zhuǎn)string

    再使用整型轉(zhuǎn)string的時候感覺有點棘手,因為itoa不是標準C里面的,而且即便是有itoa,其他類型轉(zhuǎn)string不是很方便。后來去網(wǎng)上找了一下,發(fā)現(xiàn)有一個好方法
    2013-09-09
  • 最新C語言中g(shù)etchar的使用

    最新C語言中g(shù)etchar的使用

    getchar()是在輸入緩沖區(qū)順序讀入一個字符(包括空格、回車和Tab) ,getchar()是stdio.h中的庫函數(shù),它的作用是從stdin流中讀入一個字符,本文給大家介紹getchar的使用,感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • C++實現(xiàn)神經(jīng)網(wǎng)絡框架SimpleNN的詳細過程

    C++實現(xiàn)神經(jīng)網(wǎng)絡框架SimpleNN的詳細過程

    本來自己想到用C++實現(xiàn)神經(jīng)網(wǎng)絡主要是想強化一下編碼能力并入門深度學習,對C++實現(xiàn)神經(jīng)網(wǎng)絡框架SimpleNN的詳細過程感興趣的朋友一起看看吧
    2021-08-08
  • 一文帶你初識C++和命名空間

    一文帶你初識C++和命名空間

    C++是在C語言基礎(chǔ)上發(fā)展的面向?qū)ο笳Z言,C++支持過程化、面向?qū)ο蠹俺橄髷?shù)據(jù)類型的程序設計,C++的發(fā)展包括多個版本,下面這篇文章主要介紹了一文帶你初識C++和命名空間的相關(guān)資料,需要的朋友可以參考下
    2024-10-10
  • 淺析C++編程當中的線程

    淺析C++編程當中的線程

    這篇文章主要介紹了淺析C++編程當中的線程,線程在每一種編程語言中都是重中之重,需要的朋友可以參考下
    2015-07-07
  • C++概念重載、覆蓋、隱藏的使用說明

    C++概念重載、覆蓋、隱藏的使用說明

    本篇文章介紹了,在C++中概念重載、覆蓋、隱藏的使用分析說明。需要的朋友參考下
    2013-05-05
  • 推薦幾款實用的C++ 在線工具

    推薦幾款實用的C++ 在線工具

    這篇文章主要推薦了幾款實用的C++ 在線工具,幫助大家更好的進行c++開發(fā),感興趣的朋友可以了解下載。
    2020-10-10
  • Qt 自定義分頁控件的實現(xiàn)

    Qt 自定義分頁控件的實現(xiàn)

    在應用程序開發(fā)時經(jīng)常會遇到數(shù)據(jù)分頁的需求,每一頁展示特定數(shù)量的數(shù)據(jù),通過點擊按鈕翻頁或者輸入頁碼跳轉(zhuǎn)到指定頁,本文就來介紹一下Qt 自定義分頁控件的實現(xiàn),感興趣的可以了解一下
    2023-11-11
  • vscode刷acm、leetcode的題目

    vscode刷acm、leetcode的題目

    vscode是一款越來越受碼農(nóng)們喜愛的軟件,大多數(shù)人學習編程繞不開的一部分就是算法,很多人都喜歡刷LeetCode的題目,本文就來介紹一下
    2021-06-06
  • C++面向?qū)ο笳Z言自制多級菜單功能實現(xiàn)代碼

    C++面向?qū)ο笳Z言自制多級菜單功能實現(xiàn)代碼

    菜單類主要負責菜單的創(chuàng)建、修改、刪除,是包含菜單結(jié)構(gòu)組織和響應函數(shù)的模型,用戶擁有充分的自主性,可根據(jù)需要自定義菜單顯示和響應函數(shù),這篇文章主要介紹了C++面向?qū)ο笳Z言自制多級菜單,需要的朋友可以參考下
    2024-06-06

最新評論

石门县| 逊克县| 随州市| 连云港市| 庄河市| 日土县| 临朐县| 南安市| 册亨县| 泉州市| 晋中市| 永善县| 于都县| 灵武市| 汉源县| 随州市| 兴安县| 囊谦县| 绥滨县| 奈曼旗| 宿迁市| 长丰县| 安化县| 闽清县| 南木林县| 琼中| 嘉鱼县| 定安县| 东辽县| 左云县| 隆林| 靖边县| 新邵县| 化德县| 嵊州市| 夏河县| 图片| 木里| 酒泉市| 北碚区| 壶关县|