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

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

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

介紹

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

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

項(xiàng)目名稱說明

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

設(shè)計(jì)思路

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

項(xiàng)目進(jìn)度

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

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

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

Json 節(jié)點(diǎn)類型定義

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

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

Json 節(jié)點(diǎn)定義

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

接口說明

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

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

接口列表

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

編程示例

簡單使用示例

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

詳情請(qǐng)參看demo.cpp或tests目錄下的測(cè)試用例

項(xiàng)目地址

https://gitee.com/zhoutk/zjson

https://github.com/zhoutk/zjson

運(yùn)行方法

該項(xiàng)目在vs2019, gcc7.5, clang12.0下均編譯運(yùn)行正常。

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ù)會(huì)有一系列相關(guān)項(xiàng)目出爐,更多關(guān)于C++17實(shí)現(xiàn)JSON庫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于C++ string和c類型字符數(shù)組的對(duì)比

    關(guān)于C++ string和c類型字符數(shù)組的對(duì)比

    下面小編就為大家?guī)硪黄P(guān)于C++ string和c類型字符數(shù)組的對(duì)比。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-07-07
  • C語言基礎(chǔ)使用IDE快速開發(fā)的方法

    C語言基礎(chǔ)使用IDE快速開發(fā)的方法

    這篇文章主要介紹了C語言基礎(chǔ)使用IDE快速開發(fā)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 基于C語言實(shí)現(xiàn)的貪吃蛇游戲完整實(shí)例代碼

    基于C語言實(shí)現(xiàn)的貪吃蛇游戲完整實(shí)例代碼

    這篇文章主要介紹了基于C語言實(shí)現(xiàn)的貪吃蛇游戲完整實(shí)例代碼,對(duì)于學(xué)習(xí)游戲開發(fā)的朋友有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08
  • C語言深入講解之從函數(shù)棧幀角度理解return關(guān)鍵字

    C語言深入講解之從函數(shù)棧幀角度理解return關(guān)鍵字

    在C語言中,一般情況下函數(shù)的返回值是通過函數(shù)中的return語句來實(shí)現(xiàn)的,每調(diào)用一次return語句只能從函數(shù)中返回一個(gè)值,這篇文章主要給大家介紹了關(guān)于C語言從函數(shù)棧幀角度理解return關(guān)鍵字的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • C++設(shè)計(jì)模式之策略模式(Strategy)

    C++設(shè)計(jì)模式之策略模式(Strategy)

    這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之策略模式Strategy ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C語言中的隱式函數(shù)聲明

    C語言中的隱式函數(shù)聲明

    在c語言里面開來還是要學(xué)習(xí)c++的編程習(xí)慣,使用函數(shù)之前一定要聲明。不然,即使編譯能通過,運(yùn)行時(shí)也可能會(huì)出一些莫名其妙的問題。
    2016-01-01
  • C語言實(shí)現(xiàn)經(jīng)典掃雷小游戲完整代碼(遞歸展開?+?選擇標(biāo)記)

    C語言實(shí)現(xiàn)經(jīng)典掃雷小游戲完整代碼(遞歸展開?+?選擇標(biāo)記)

    這篇文章主要介紹了C語言小項(xiàng)目之掃雷游戲帶遞歸展開?+?選擇標(biāo)記效果,本代碼中,我們用字符?!?來標(biāo)識(shí)雷,文中附有完整代碼,需要的朋友可以參考下
    2022-05-05
  • C語言數(shù)據(jù)類型與sizeof關(guān)鍵字

    C語言數(shù)據(jù)類型與sizeof關(guān)鍵字

    這篇文章主要介紹了C語言數(shù)據(jù)類型與sizeof關(guān)鍵字,C語言的數(shù)據(jù)類型包括基本類型、構(gòu)造類型、指針類型以及空類型,下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-04-04
  • C++繼承介紹

    C++繼承介紹

    C++繼承可以是單一繼承或多重繼承,每一個(gè)繼承連接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作

    C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作

    這篇文章主要介紹了C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01

最新評(píng)論