概要:json11是一个基于c++11的json解析库,dropbox出品。

使用

直接举自带单元测试test.cpp中的例子:

    const string simple_test =
R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})"; string err;
const auto json = Json::parse(simple_test, err); std::cout << "k1: " << json["k1"].string_value() << "\n";
std::cout << "k3: " << json["k3"].dump() << "\n"; for (auto &k : json["k3"].array_items()) {
std::cout << " - " << k.dump() << "\n";
}

Json::parse可以解析string字符串生成Json对象,dump()则将Json对象格式化为字符串形式。

Json类提供了多种构造函数,用来构造Json对象:

    const Json obj = Json::object({
{ "k1", "v1" },
{ "k2", 42.0 },
{ "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
});

设计

主要由以下几个类构成

  • class Json
  • class JsonValue
  • class Value
  • class JsonInt JsonDouble ...

Json类为对外开放的接口,有多种构造方式。

class Json final {
public
// Types
enum Type {
NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
};
typedef std::vector<Json> array; //array、object直接使用STL容器实现
typedef std::map<std::string, Json> object; Json() noexcept; // NUL
Json(std::nullptr_t) noexcept; // NUL
Json(double value); // NUMBER
Json(int value); // NUMBER
Json(bool value); // BOOL
Json(const std::string &value); // STRING
Json(std::string &&value); // STRING
Json(const char * value); // STRING
Json(const array &values); // ARRAY
Json(array &&values); // ARRAY
Json(const object &values); // OBJECT
Json(object &&values); // OBJECT template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {} template <class M, typename std::enable_if<
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
int>::type = 0>
Json(const M & m) : Json(object(m.begin(), m.end())) {}
template <class V, typename std::enable_if<
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
int>::type = 0>
Json(const V & v) : Json(array(v.begin(), v.end())) {}
Json(void *) = delete; ... private:
std::shared_ptr<JsonValue> m_ptr;

其中有几个构造函数比较复杂,详见:

这些数据的实体被存放在m_ptr所指向的对象之中。

class JsonValue {
protected:
friend class Json;
friend class JsonInt;
friend class JsonDouble;
virtual Json::Type type() const = 0;
virtual bool equals(const JsonValue * other) const = 0;
virtual bool less(const JsonValue * other) const = 0;
virtual void dump(std::string &out) const = 0;
virtual double number_value() const;
virtual int int_value() const;
virtual bool bool_value() const;
virtual const std::string &string_value() const;
virtual const Json::array &array_items() const;
virtual const Json &operator[](size_t i) const;
virtual const Json::object &object_items() const;
virtual const Json &operator[](const std::string &key) const;
virtual ~JsonValue() {}
};

JsonValue是一个抽象基类,定义了一些api,用来操作访问json对象。这些api并不向用户开放,用于内部使用。用户借由Json类中提供的函数来操作和访问。

接下来是其派生类Value:

template <Json::Type tag, typename T>
class Value : public JsonValue {
protected: // Constructors
explicit Value(const T &value) : m_value(value) {}
explicit Value(T &&value) : m_value(move(value)) {} // Get type tag
Json::Type type() const override {
return tag;
} // Comparisons
bool equals(const JsonValue * other) const override {
return m_value == static_cast<const Value<tag, T> *>(other)->m_value;
}
bool less(const JsonValue * other) const override {
return m_value < static_cast<const Value<tag, T> *>(other)->m_value;
} const T m_value;
void dump(string &out) const override { json11::dump(m_value, out); }
};

Value作为一个类模板,实例化出不同的类保存着json对象的数据实体。

而JsonInt,JsonDouble等等类可以直接通过继承对应的实例化类来保存数据。

以JsonInt为例:

class JsonInt final : public Value<Json::NUMBER, int> {
double number_value() const override { return m_value; }
int int_value() const override { return m_value; }
bool equals(const JsonValue * other) const override { return m_value == other->number_value(); }
bool less(const JsonValue * other) const override { return m_value < other->number_value(); }
public:
explicit JsonInt(int value) : Value(value) {}
};

继承的Value为int版本,因此可以直接通过父类构造函数来保存value。同时实现了专属于该类的一些操作,例如int_value()用来获取value的值。

json11阅读的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  3. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  4. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  5. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  6. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  7. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. 二维数组的查找(JAVA)

    二维数组查找 解题思路:找到该二维数组的特殊点,易知该二维数组左下角的那个点很特殊.从这个点往右看,数值都在变大:而往上看,数值都在变小.所以 我们可以将这个点的索引设为起点(i,j),当比目标数大时 ...

  2. 安装Kerberos后,如何不使用它,Current Kerberos password:

    在不知情的情况下,安装了kerberos,然后只有是有密码的地方,一直有这个: Current Kerberos password: 没有了解过kerberos,想要卸载,卸载了还是有,怎么弄都弄不掉 ...

  3. Written a lua threadpool

    工作原理 由于lua只能单线程运行,该lib要求所有lua代码在单线程,而多线程部分只能为c代码 具体用法上要求多线程部分必须用c实现 相关模块 线程池 异步函数实现框架 Now only a sle ...

  4. 黄聪:谷歌验证 (Google Authenticator) 的实现原理是什么?

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:徐小花链接:http://www.zhihu.com/question/20462696/answer/18731073来源: ...

  5. [蓝桥杯]ALGO-181.算法训练_According to Bartjens

    问题描述 计算器和计算机的大量普及也有其弊端.即便是受过专业技术训练的学生们也很可能缺乏计算能力.由于电脑的大量使用,很多人无法心算出7*8这样的算式,甚至是用纸和笔也算不出13*.不过谁在意呢? B ...

  6. Linux(centos 7)配置tomcat8、JDK1.8、lighttpd、ngnix、mysql

    JDK 下载好后使用 rpm -ivh jdk-7u25-linux-x64.rpm 进行安装. 安装好后编辑 /etc/profile 文件,在末尾加上: 1 2 3 export JAVA_HOM ...

  7. 报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1

    错误现象: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-com ...

  8. [转]Java事件处理机制- 事件监听器的四种实现方式

    原文来自http://stefan321.iteye.com/blog/345221 自身类作为事件监听器 外部类作为事件监听器 匿名内部类作为事件监听器 内部类作为事件监听器 自身类作为事件监听器: ...

  9. js 一些方法

    1.js去除字符串前后的空格 function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } 2.js打乱数组的顺 ...

  10. Android 开发 系统组件集合

    常用的TextView.Button.ImageView和几个常用布局就不介绍了,我们介绍一些特别好用但是常常忘记的组件. 标题栏组件 <androidx.appcompat.widget.To ...