c++原生指针无法直接处理json动态类型,因其缺乏运行时类型系统,而nlohmann::json*等库指针通过类型擦除封装了安全访问逻辑。

JSON动态类型在C++里为什么不能直接用原生指针
C++没有运行时类型系统,int*、std::string* 这类原生指针无法指向“可能是字符串也可能是对象还可能是null”的JSON值。硬写 void* 不仅失去类型安全,还会让解析逻辑散落在各处,极易崩溃。
真正可行的路径只有一条:用支持运行时类型擦除的JSON库指针(如 nlohmann::json* 或 rapidjson::Value*),它们内部已封装好类型判别与访问逻辑。
用 nlohmann::json* 安全访问嵌套动态字段
假设你拿到一个 nlohmann::json* 指向的JSON文档,要取 data.user.name,但不确定 data 是否存在、user 是否为对象、name 是否为字符串——这时不能直接链式解引用。
- 先检查指针是否非空:
if (!j_ptr) return; - 用
operator[]访问字段前,先用contains()或is_object()做守卫:if (j_ptr->contains("data") && (*j_ptr)["data"].is_object()) - 字符串取值必须显式调用
get<:string>()</:string>,不能直接(*j_ptr)["data"]["user"]["name"].dump()—— 那返回的是JSON字符串,不是原始内容 - 对可能为
null的字段,用is_null()判断比捕获异常更轻量
rapidjson::Value* 的类型转换陷阱
rapidjson::Value* 更底层,类型判断靠 .IsString()、.IsObject() 等成员函数,但它的指针不自动管理生命周期——如果它指向栈上临时解析结果,外部指针立刻悬空。
- 永远确保
rapidjson::Value*指向的内存由Document实例长期持有,不要从局部Parse()返回的临时Value取地址 - 访问数组元素时,
value[0]不会越界检查,必须先用value.Size()校验长度 - 从
Value*读字符串要用value->GetString(),且该指针仅在Document生命周期内有效;想持久化就得std::string(value->GetString()) -
GetInt()等转换函数在类型不匹配时不抛异常,而是返回0或未定义值——必须先IsInt()再取
自定义结构体映射时,指针和引用怎么选
当把JSON反序列化进自定义结构体(如 User),别用裸指针存字段,改用 std::optional<:string></:string> 或 std::unique_ptr<user></user> 表达可选性与所有权。
- 若JSON中
"age"可能缺失或为null,结构体字段声明为std::optional<int> age;</int>,解析时用j["age"].is_number_integer()判断后再赋值 - 嵌套对象字段(如
"address")用std::unique_ptr<address></address>,避免复制开销,也明确表达“可能为空”语义 - 禁止把
nlohmann::json::iterator存为成员指针——迭代器失效成本高,且JSON修改后立即不可用
动态类型的本质是运行时分支,所有指针操作都得让位于类型检查。漏掉一次 is_string() 或多写一个 operator* 解引用,就可能触发断言失败或静默数据截断。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











