C++ 使用 jsoncpp 编写代码优化,提高人类友好程度

优化后部分折叠的代码

一、背景说明

日常使用 jsoncpp创建 Json 时,经常需要先创建子 json ,对子 json 赋值完毕,然后再保存到父 json 中,这种代码结构与人类的逻辑不一致,造成编写、阅读与理解上的困难。

二、优化发现

前几天使用 cpp-httplib 时,看到代码中大量使用 lambda 回调函数 ,使代码简捷程度大幅提升。今天使用 jsonCpp 时,对于先创建对象再赋值保存非常不满,于是动手改造后,大幅提高了人类友好程度

三、灵感创造

如果"json[‘key’]="后面可以直接编写函数返回 “Json::Value” ,那么人性化的添加顺序就可以达到,就不会再需要在添加该对象前初始化。lambda 函数可以随用随申请,写到右值位置十分合适,但是左值要求的类型并不是函数,因此可以调用一个用于返回左值类型的函数,参数填充要调用的 lambda 表达式,这样就可以两全其美了。因此构造了一个中间函数。

下面的代码中,关键部分为第二行的这个中间函数,作用为调用传入的 lambda 函数,返回左值需要的类型

    std::function<Json::Value()>runs = [&]()->Json::Value {
    
     return Json::Value(); };  // 需要传入/构造的函数
    auto func = [&](std::function<Json::Value()>f){
    
     return f(); };   // 关键函数
    Json::Value val = func(runs); // 可正常调用

注意:std::function、auto、lambda 都要求 C++11 及以上,编译时可添加 –std=c++11 参数

四、代码实践

1.要生成的 json

{
    
    
    "graden": "six",
    "leaders": [
        "sam",
        "tim"
    ],
    "students": [
        {
    
    
            "name": "andy",
            "sex": "boy"
        },
        {
    
    
            "name": "alice",
            "sex": "girl"
        }
    ],
    "teacher": "tom"
}

2.传统构造方法

层次不清晰,顺序不符合人类直觉,且不易在 IDE 中进行代码折叠。

void classJson(){
    
    
    // 传统构造json的方法
    Json::Value jClass;
    jClass["graden"]  = "six";

    jClass["teacher"] = "tom";

    Json::Value jLeader;
    jLeader.append("sam");
    jLeader.append("tim");
    jClass["leaders"] = jLeader;

    Json::Value jStudents;
    Json::Value jItem;
    jItem["name"] = "andy";
    jItem["sex"]  = "boy";
    jStudents.append(jItem);
    jItem.clear();
    jItem["name"] = "alice";
    jItem["sex"]  = "girl";
    jStudents.append(jItem);
    jClass["students"] = jStudents;
    
    // 输出生成的字符串
    Json::FastWriter write;
    cout << write.write(jClass) << endl;
}

3.优化后的代码

在代码折叠后依旧符合人类直觉。

void specialJson(){
    
    
    // 奇巧构造json的方法  // c++11:std::function/lambda/auto
    std::function<Json::Value()>runs = [&]()->Json::Value {
    
     return Json::Value(); };  // 需要传入/构造的函数
    auto func = [&](std::function<Json::Value()>f){
    
     return f(); };   // 关键函数
    Json::Value val = func(runs); // 可正常调用
    
    // 具体实现
    Json::Value jSpecial;
    jSpecial["graden"]  = "six";
    jSpecial["teacher"] = "tom";
    jSpecial["leaders"] = func([&]()->Json::Value {
    
    
        Json::Value jLeaders;
        jLeaders.append("sam");
        jLeaders.append("tim");
        return jLeaders;
    });
    jSpecial["students"] = func([&]()->Json::Value {
    
    
        Json::Value jStudents;
        jStudents.append(func([&]()->Json::Value {
    
    
            Json::Value jAndy;
            jAndy["name"] = "andy";
            jAndy["sex" ] = "boy";
            return jAndy;
        }));
        jStudents.append(func([&]()->Json::Value {
    
    
            Json::Value jALice;
            jALice["name"] = "alice";
            jALice["sex"]  = "girl";
            return jALice;
        }));
        return jStudents;
    });
    
    // 输出生成的字符串
    Json::FastWriter write;
    cout << write.write(jSpecial) << endl;
}

4.输出结果

{
    
    "graden":"six","leaders":["sam","tim"],"students":[{
    
    "name":"andy","sex":"boy"},{
    
    "name":"alice","sex":"girl"}],"teacher":"tom"}

{
    
    "graden":"six","leaders":["sam","tim"],"students":[{
    
    "name":"andy","sex":"boy"},{
    
    "name":"alice","sex":"girl"}],"teacher":"tom"}

5.完整代码

//  main.cpp
//  Created by Guoiaoang on 2021/12/6.

#include <iostream>
#include "json/json.h"
using namespace std;

/*
{
  "graden": "six",
  "teacher": "tom",
  "leaders": [
    "sam",
    "tim"
  ],
  "students": [
    {
      "name": "andy",
      "sex": "boy"
    },
    {
      "name": "alice",
      "sex": "girl"
    }
  ]
}
*/

void classJson(){
    
    
    // 传统构造json的方法
    Json::Value jClass;
    jClass["graden"]  = "six";

    jClass["teacher"] = "tom";

    Json::Value jLeader;
    jLeader.append("sam");
    jLeader.append("tim");
    jClass["leaders"] = jLeader;

    Json::Value jStudents;
    Json::Value jItem;
    jItem["name"] = "andy";
    jItem["sex"]  = "boy";
    jStudents.append(jItem);
    jItem.clear();
    jItem["name"] = "alice";
    jItem["sex"]  = "girl";
    jStudents.append(jItem);
    jClass["students"] = jStudents;
    
    // 输出生成的字符串
    Json::FastWriter write;
    cout << write.write(jClass) << endl;
}

void specialJson(){
    
    
    // 奇巧构造json的方法  // c++11:std::function/lambda/auto
    std::function<Json::Value()>runs = [&]()->Json::Value {
    
     return Json::Value(); };  // 需要传入/构造的函数
    auto func = [&](std::function<Json::Value()>f){
    
     return f(); };   // 关键函数
    Json::Value val = func(runs); // 可正常调用
    
    // 具体实现
    Json::Value jSpecial;
    jSpecial["graden"]  = "six";
    jSpecial["teacher"] = "tom";
    jSpecial["leaders"] = func([&]()->Json::Value {
    
    
        Json::Value jLeaders;
        jLeaders.append("sam");
        jLeaders.append("tim");
        return jLeaders;
    });
    jSpecial["students"] = func([&]()->Json::Value {
    
    
        Json::Value jStudents;
        jStudents.append(func([&]()->Json::Value {
    
    
            Json::Value jAndy;
            jAndy["name"] = "andy";
            jAndy["sex" ] = "boy";
            return jAndy;
        }));
        jStudents.append(func([&]()->Json::Value {
    
    
            Json::Value jALice;
            jALice["name"] = "alice";
            jALice["sex"]  = "girl";
            return jALice;
        }));
        return jStudents;
    });
    
    // 输出生成的字符串
    Json::FastWriter write;
    cout << write.write(jSpecial) << endl;
}

int main(int argc, const char * argv[]) {
    
    
    classJson();
    specialJson();
    getchar();
    return EXIT_SUCCESS;
}

五、优化方向

该函数应该使用模板进行构造,以便提高代码的通用性。

六、参考使用

1.cpp-httplib
2.jsoncpp

猜你喜欢

转载自blog.csdn.net/u012101384/article/details/121757198