在C++项目里,把内存中的对象变成可传输的JSON字符串是接口开发中的常见需求。nlohmann_json是一个仅头文件的现代C++库,它用非常轻量的方式解决了对象到JSON的映射问题,不需要复杂的宏或者代码生成工具。

为什么选择nlohmann_json做对象转换
nlohmann_json的设计哲学是让JSON成为一种像内置类型一样好用的数据结构。它不要求你的类继承某个基类,也不强制你写大量的getter和setter。只要提供一个自由的转换函数,编译器就能在需要时自动找到对应的序列化逻辑。这种方式对已有代码侵入性极小,特别适合在遗留系统中逐步接入。
相比手动用字符串拼接或者借助第三方代码生成器,nlohmann_json在类型安全上优势明显。比如字符串里的双引号、反斜杠会被自动转义,数字和布尔值也能按JSON规范输出。另外它原生支持STL容器,像std::vector、std::map都可以直接丢进json对象里,不需要额外适配。
基础结构体如何转为JSON字符串
最核心的做法是为你的类型特化两个自由函数:to_json和from_json。其中to_json负责把对象字段写进nlohmann::json引用里。下面代码展示了一个最简单的用户结构体转换方式。
#include <nlohmann/json.hpp>
#include <string>
using json = nlohmann::json;
struct User {
int id;
std::string name;
bool active;
};
// 将User写入json对象
void to_json(json& j, const User& u) {
j = json{
{"id", u.id},
{"name", u.name},
{"active", u.active}
};
}
// 从json对象读回User
void from_json(const json& j, User& u) {
j.at("id").get_to(u.id);
j.at("name").get_to(u.name);
j.at("active").get_to(u.active);
}
#include <iostream>
int main() {
User u{1, "张三", true};
json j = u;
// 转换为JSON字符串
std::string s = j.dump();
std::cout << s << std::endl;
return 0;
}
上面的to_json函数把结构体成员映射到JSON的键值对。调用json j = u;时,编译器会自动匹配我们写的自由函数。随后用dump()方法就能得到压缩后的JSON文本,如果传入参数如dump(4)还能得到带缩进的可读格式。
需要注意,字段名用的是C++里的字符串字面量,它们会成为JSON里的key。如果结构体字段很多,这种写法虽然直观,但容易漏写。实际项目中可以配合代码宏或者少量脚本检查,保证结构和JSON的一致性。
处理私有成员与嵌套对象
当结构体有私有成员时,外部的自由函数无法直接访问。此时可以把to_json声明为类的友元,或者在类内部提供一个公开的序列化接口。下面示例展示了友元方式,这样既能封装数据,也不破坏转换逻辑。
#include <nlohmann/json.hpp>
#include <string>
using json = nlohmann::json;
class Account {
private:
int balance;
std::string owner;
public:
Account(int b, std::string o) : balance(b), owner(o) {}
friend void to_json(json& j, const Account& a);
};
void to_json(json& j, const Account& a) {
j = json{
{"balance", a.balance},
{"owner", a.owner}
};
}
如果对象里还包含其他自定义类型,只要那个类型也有自己的to_json,nlohmann_json会递归调用。比如一个部门对象里放了User数组,不需要手写循环,直接赋值即可。这种组合能力让复杂业务模型的导出变得简单。
对于嵌套结构,建议保持每层转换函数职责单一。不要在一个to_json里写太多业务判断,否则后续维护时很难定位某个字段为什么出错。把嵌套类型各自管好自己,整体序列化自然就清晰了。
容器、智能指针与枚举的序列化
STL容器是天然支持的。std::vector<User>可以直接赋给json,库会逐个调用User的to_json。智能指针方面,std::shared_ptr<User>也能处理,不过要确认指针不为空,或者提前在代码里做空值判断,避免运行时异常。
#include <nlohmann/json.hpp>
#include <vector>
#include <memory>
using json = nlohmann::json;
enum class Status { Ok, Error };
void to_json(json& j, const Status& s) {
j = (s == Status::Ok) ? "ok" : "error";
}
int main() {
std::vector<User> users{{1, "a", true}, {2, "b", false}};
json j = users;
std::shared_ptr<User> p = std::make_shared<User>(3, "c", true);
json jp = *p;
json js = Status::Ok;
return 0;
}
枚举类型本身不是JSON原生支持的,所以写成to_json把它转成字符串或数字更直观。上面代码把Status变成了字符串,前端解析时不容易误解。智能指针这里演示了解引用后赋值,如果可能为空的场景,可以先判断再决定写入null还是对象。
用nlohmann_json做对象到字符串的转换,整体思路就是“为类型写好映射,让库去递归处理”。它不魔法,但足够贴合C++的零开销理念。掌握基础结构体和容器的写法后,绝大多数业务对象的导出需求都能在几十行代码内稳定解决。
C++nlohmann_json对象序列化修改时间:2026-08-01 07:57:27