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

如何手动实现C++对象到二进制文件的序列化与反序列化(无第三方库)

手动实现C++二进制序列化/反序列化的方案

核心逻辑:所有动态长度类型(std::string、std::vector等)的序列化都遵循「先写入长度值,再写入对应长度的二进制内容」的规则,固定大小类型(如int)可以直接写入二进制内容,读写时保持顺序一致即可。

具体实现代码

你可以直接在Student类中新增序列化、反序列化的成员方法,封装所有二进制读写逻辑:

#include <fstream>
#include <string>
#include <vector>

class Student{
    std::string name, email, telephoneNo;
    int addmissionNo;
    std::vector<std::string> issued_books;
public:
    // 原有构造、字段初始化等方法保留

    // 序列化:将当前对象写入二进制输出流
    void serialize(std::ofstream& out) const {
        // 1. 写入固定大小的int字段
        out.write(reinterpret_cast<const char*>(&addmissionNo), sizeof(addmissionNo));

        // 2. 写入所有string类型字段
        serialize_string(out, name);
        serialize_string(out, email);
        serialize_string(out, telephoneNo);

        // 3. 写入vector<string>字段:先存vector长度,再逐个序列化内部字符串
        size_t book_count = issued_books.size();
        out.write(reinterpret_cast<const char*>(&book_count), sizeof(book_count));
        for (const auto& book : issued_books) {
            serialize_string(out, book);
        }
    }

    // 反序列化:从二进制输入流读取内容填充当前对象
    void deserialize(std::ifstream& in) {
        // 1. 读取固定大小的int字段
        in.read(reinterpret_cast<char*>(&addmissionNo), sizeof(addmissionNo));

        // 2. 读取所有string类型字段
        deserialize_string(in, name);
        deserialize_string(in, email);
        deserialize_string(in, telephoneNo);

        // 3. 读取vector<string>字段
        size_t book_count;
        in.read(reinterpret_cast<char*>(&book_count), sizeof(book_count));
        issued_books.resize(book_count);
        for (size_t i = 0; i < book_count; ++i) {
            deserialize_string(in, issued_books[i]);
        }
    }

private:
    // 封装string的通用序列化逻辑
    void serialize_string(std::ofstream& out, const std::string& str) const {
        size_t len = str.size();
        // 先写字符串长度
        out.write(reinterpret_cast<const char*>(&len), sizeof(len));
        // 再写字符串实际内容
        out.write(str.data(), len);
    }

    // 封装string的通用反序列化逻辑
    void deserialize_string(std::ifstream& in, std::string& str) {
        size_t len;
        // 先读字符串长度
        in.read(reinterpret_cast<char*>(&len), sizeof(len));
        str.resize(len);
        // 再读对应长度的内容
        in.read(str.data(), len);
    }
};

使用示例

int main() {
    // 序列化写入文件
    Student s1;
    // 此处省略s1各个字段的赋值逻辑
    std::ofstream out_file("student.dat", std::ios::binary);
    s1.serialize(out_file);
    out_file.close();

    // 反序列化读取文件
    Student s2;
    std::ifstream in_file("student.dat", std::ios::binary);
    s2.deserialize(in_file);
    in_file.close();
    return 0;
}

注意事项

  • 读写文件必须指定std::ios::binary标志,否则Windows平台会自动转义换行符,导致二进制内容错乱。
  • 如果需要先将对象序列化到内存缓冲区再批量写入文件,只需要将serialize/deserialize方法的参数替换为std::stringstream,同时指定std::ios::binary打开模式即可,内部读写逻辑不需要修改。
  • 上述实现默认读写在同一架构、同一编译器的设备上运行,如果需要跨平台兼容,需要额外处理大小端、类型长度差异问题(比如固定用int32_t存储长度,序列化前统一转成大端/小端字节序,反序列化后转成本地字节序)。
  • 如果类包含指针类型成员,不能直接写入指针地址,需要按照动态类型的处理思路,序列化指针指向的实际内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:57:03