概要: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. 常见模块(五) random模块

    random随机函数中的常用方法 1.random.random 返回一个介于左闭右开[0.0, 1.0)区间的浮点数 print(random.random()) 2.random.randrang ...

  2. Inotify机制的简单应用

    编程之路刚刚开始,错误难免,希望大家能够指出. 一.Inotify机制 1.简单介绍inotify:Inotify可用于检测单个文件,也可以检测整个目录.当检测的对象是一个目录的时候,目录本身和目录里 ...

  3. 【Jmeter】api性能测试总结

    1.前提概念 平时常用的性能测试:api性能测试+场景性能测试:今天就说一说api性能测试 2.如何进行性能测试? 需求:对某api进行性能测试,看看最大承受的并发数,分析下图表 分析: 错误思路:当 ...

  4. GanttProject 项目管理软件的优点

    GanttProject 的优点 GanttProject 是一款基于 GPL 协议的开源软件,代码完全开源,使用的是 Java 语言编写. 最近在试用,有以下一些优大. 文件格式为 xml,这个是我 ...

  5. 数字证书的理解以及自建CA机构颁发证书

    一.理解什么是数字证书   http://www.cnblogs.com/JeffreySun/archive/2010/06/24/1627247.html    理解数字证书等概念,无数次想好好看 ...

  6. python实现Content-Type类型为application/x-www-form-urlencoded发送POST请求

    周日晚上接到公司的电话需要通过新榜的接口拿下微博热搜数据,拿到接口文档看了下很简单的一个post请求,主要根据时间段来获取热搜数据. 在实际编码的过程中经常遇到header的Content-Type的 ...

  7. 微信支付,退款时,出现了内部错误-网站中X509Certificate2加载证书时出错

    今天给阿里云,虚拟主机 网站配置了加密证书文件,用类X509Certificate2加载证书文件时,一直报出现了内部错误,但是Demo中用控制台程序加载证书没任何问题 读取证书文件的语句: X509C ...

  8. c# 状态机实现

    c#仿boost statechart的状态机.去年转到unity使用c#,statechart原来的风格蛮爽的,缺点是编译忒慢,在c#则编译根本不是问题. 不一样的地方首先是简单!因为没做一些东西如 ...

  9. Python 输出

    普通的输出 生活中的“输出”: 软件中的“输出”: python中变量的输出: print('hello world') 格式化输出 占位符% print('Hello,%s' % 'Python') ...

  10. mysql 计算两点经纬度之间的距离含具体sql语句

    mysql距离计算,单位m,以及排序 lon 经度 lat 纬度 一般地图上显示的坐标顺序为,纬度在前(范围-90~90),经度在后(范围-180~180) 首先新建一张表,里面包含经纬度 SET F ...