You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Json11源代码中静态全局结构体的疑问

嘿,我来帮你拆解这段Json11里的代码,当初我第一次看这段的时候也琢磨了好一会儿呢!

首先先把你那段截断的代码补全(应该是下面这样):

/* * * * * * * * * * * * * * * * * * * * * Static globals - static-init-safe */
struct Statics {
    const std::shared_ptr<JsonValue> null = make_shared<JsonNull>();
    const std::shared_ptr<JsonValue> t = make_shared<JsonBoolean>(true);
    const std::shared_ptr<JsonValue> f = make_shared<JsonBoolean>(false);
    const string empty_string;
    const vector<Json> empty_vector;
    const map<string, Json> empty_map;
};

这段代码的核心是解决C++里的静态初始化顺序问题,同时实现JSON基础类型实例的全局复用。

我给你逐个拆解每个部分的作用:

  • null/t/f:这三个是JSON里最基础的null、true、false值的实例,用std::shared_ptr包裹后全局复用。这样每次需要返回JSON null/布尔值时,不用重新创建新对象,直接返回这些指针就行,既省内存又高效。
  • empty_string/empty_vector/empty_map:对应空的JSON字符串、数组、对象的容器实例。当Json11需要返回空的JSON类型时,直接返回这些全局空实例的引用,避免每次创建新的空容器。

而为什么要把这些变量塞进一个Statics结构体里?关键在于注释里的static-init-safe——C++里不同编译单元的全局静态变量初始化顺序是不确定的,如果直接把这些变量定义成全局的,很可能出现某个代码在这些变量初始化前就使用它们的情况,导致未定义行为。

Json11的常规做法是把这个Statics实例放在一个静态函数里,比如:

static const Statics& get_statics() {
    static Statics s;
    return s;
}

这样一来,Statics里的所有成员会在第一次调用get_statics()时才初始化,而且C++11及以后标准保证静态局部变量的初始化是线程安全的,完美规避了静态初始化顺序的坑。

说白了,这段代码就是用一种安全的方式,提供全局可复用的JSON基础类型实例,兼顾了性能和初始化安全性。

内容的提问来源于stack exchange,提问作者ehds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:17:45