C++中序列化常用JSON、二进制、Protobuf或自定义方法;JSON易读适合配置,用nlohmann/json库实现对象与JSON互转;二进制高效但限POD类型且需处理字节序;Protobuf跨语言高性能,需定义.proto文件生成代码;自定义接口灵活但需手动管理字段读写与内存。

在C++中实现数据的序列化和反序列化,通常需要将对象转换为字节流以便存储或传输,然后再还原为原始对象。由于C++标准库没有内置的序列化机制,开发者需借助自定义方法或其他工具来完成。
使用JSON进行序列化与反序列化
JSON是一种轻量、易读的数据交换格式,适合配置文件或网络通信。通过第三方库如 nlohmann/json 可以轻松实现C++对象与JSON之间的转换。
示例代码:
#include#include struct Person { std::string name; int age; }; // 序列化 void to_json(nlohmann::json& j, const Person& p) { j = nlohmann::json{{"name", p.name}, {"age", p.age}}; } // 反序列化 void from_json(const nlohmann::json& j, Person& p) { j.at("name").get_to(p.name); j.at("age").get_to(p.age); } int main() { Person p{"Alice", 30}; // 转为JSON字符串 nlohmann::json j = p; std::string json_str = j.dump(); std::cout << json_str << std::endl; // 从JSON恢复对象 auto p2 = j.get (); std::cout << p2.name << ", " << p2.age << std::endl; return 0; }
使用二进制方式进行高效序列化
对于性能要求高的场景,可采用二进制方式直接写入内存数据。适用于POD(Plain Old Data)类型。
立即学习“C++免费学习笔记(深入)”;
说明:该方法不支持复杂结构(如指针、STL容器),且跨平台时需注意字节序问题。
示例:
#include#include struct Data { int id; double value; }; // 写入二进制文件(序列化) void save_binary(const Data& d, const std::string& filename) { std::ofstream out(filename, std::ios::binary); out.write(reinterpret_cast (&d), sizeof(Data)); } // 读取二进制文件(反序列化) void load_binary(Data& d, const std::string& filename) { std::ifstream in(filename, std::ios::binary); in.read(reinterpret_cast (&d), sizeof(Data)); } int main() { Data d{1, 3.14}; save_binary(d, "data.bin"); Data loaded{}; load_binary(loaded, "data.bin"); std::cout << "ID: " << loaded.id << ", Value: " << loaded.value << std::endl; return 0; }
使用Google Protocol Buffers(Protobuf)
Protobuf是Google开发的高效、跨语言的序列化方案。需定义 .proto 文件并生成C++代码。
拍客竞拍系统是一款免费竞拍网站建设软件,任何个人可以下载使用,但未经商业授权不能进行商业活动,程序源代码开源,任何个人和企业可以进行二次开发,但不能以出售和盈利为目的。安装方法,将www文件夹里面的所有文件上传至虚拟主机,在浏览器执行http://你的域名/install.php或者直接导入数据库文件执行。本次升级优化了一下内容1,程序和模板完美分离。2,优化了安装文件。3,后台增加模板切换功能。
步骤:
- 编写 .proto 文件描述数据结构
- 使用 protoc 编译器生成 C++ 类
- 调用 SerializeToString / ParseFromString 方法
.proto 示例:
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
}
C++ 使用:
Person person;
person.set_name("Bob");
person.set_age(25);
std::string buffer;
person.SerializeToString(&buffer); // 序列化
Person recovered;
recovered.ParseFromString(buffer); // 反序列化
自定义序列化接口
对复杂类,可以设计统一的序列化接口,手动控制字段读写。
例如:
class Serializable {
public:
virtual void serialize(std::ostream& os) const = 0;
virtual void deserialize(std::istream& is) = 0;
};
struct MyData : Serializable {
int x;
std::string s;
void serialize(std::ostream& os) const override {
os.write(reinterpret_cast(&x), sizeof(x));
size_t len = s.size();
os.write(reinterpret_cast(&len), sizeof(len));
os.write(s.data(), len);
}
void deserialize(std::istream& is) override {
is.read(reinterpret_cast(&x), sizeof(x));
size_t len;
is.read(reinterpret_cast(&len), sizeof(len));
s.resize(len);
is.read(&s[0], len);
}
};
基本上就这些。选择哪种方法取决于你的需求:调试友好选JSON,性能优先考虑二进制或Protobuf,跨平台兼容性要求高推荐Protobuf。自定义方式灵活但需小心管理内存和格式一致性。









