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

C++中如何一次性存储复杂数据结构并复用至测试用例?

问题

我定义了如下复杂结构体:

struct Data{
    std::unordered_map<string, int> map1;
    shared_ptr<ClassA> ptrA;
    shared_ptr<ClassB> ptrB;
    // 其他字段...
};

在代码执行的某一迭代阶段,我希望一次性存储该结构体的状态,并将此状态作为测试用例输入到test.cpp中,比如:

Data StoredState;
UnitTest(){
   // ...
   // 使用StoredState执行操作
   // ...
}

问题:将该结构体状态存储并在测试文件中使用的最佳方式是什么?目前我想到的方法是把结构体每个字段写入文件,再手动填充StoredState,但这种方式太繁琐,有没有更优方案?

解决方案

1. 序列化/反序列化(最通用稳定)

给Data以及关联的ClassA、ClassB实现序列化逻辑,把对象状态转成可持久化的格式(如JSON、二进制),测试时直接反序列化还原成对象,完全避免手动填充。

  • JSON序列化(轻量易读):用nlohmann/json这类头文件库,无需编译依赖,给涉及的类实现序列化重载:
// 给ClassA添加JSON序列化支持
void to_json(nlohmann::json& j, const ClassA& a) {
    j["member1"] = a.member1; // 替换为ClassA的实际成员
    j["member2"] = a.member2;
}

void from_json(const nlohmann::json& j, ClassA& a) {
    j.at("member1").get_to(a.member1);
    j.at("member2").get_to(a.member2);
}

// 给Data添加JSON序列化支持
void to_json(nlohmann::json& j, const Data& d) {
    j["map1"] = d.map1;
    j["ptrA"] = *d.ptrA;
    j["ptrB"] = *d.ptrB;
}

void from_json(const nlohmann::json& j, Data& d) {
    j.at("map1").get_to(d.map1);
    d.ptrA = std::make_shared<ClassA>(j.at("ptrA").get<ClassA>());
    d.ptrB = std::make_shared<ClassB>(j.at("ptrB").get<ClassB>());
}

保存状态时:

// 假设currentState是当前要存储的结构体实例
Data currentState = getCurrentState();
nlohmann::json j = currentState;
std::ofstream out("test_state.json");
out << j.dump(4); // 格式化输出,方便查看和修改

测试文件中读取:

Data StoredState;
std::ifstream in("test_state.json");
nlohmann::json j;
in >> j;
StoredState = j.get<Data>();
  • 二进制序列化(高效紧凑):用boost::serialization或Google Protobuf。以Protobuf为例,先定义.proto文件描述数据结构:
syntax = "proto3";
message ClassAProto {
    int32 member1 = 1;
    string member2 = 2;
}

message ClassBProto {
    // 对应ClassB的成员
}

message DataProto {
    map<string, int32> map1 = 1;
    ClassAProto ptrA = 2;
    ClassBProto ptrB = 3;
}

生成C++代码后,编写转换函数在Data和DataProto之间互转,即可实现快速的序列化和反序列化,适合大规模数据或性能要求高的场景。

2. 自动生成初始化代码

在程序运行到目标状态时,自动输出能初始化StoredState的C++代码,直接复制到测试文件中使用,省去手动编写的麻烦。

示例生成函数:

void generateInitCode(const Data& state, const std::string& varName) {
    std::cout << "Data " << varName << ";\n";
    // 初始化map1
    std::cout << varName << ".map1 = {\n";
    for (const auto& [key, val] : state.map1) {
        std::cout << "    {\"" << key << "\", " << val << "},\n";
    }
    std::cout << "};\n";
    // 初始化ptrA(根据ClassA的实际成员调整)
    std::cout << varName << ".ptrA = std::make_shared<ClassA>();\n";
    std::cout << varName << ".ptrA->member1 = " << state.ptrA->member1 << ";\n";
    std::cout << varName << ".ptrA->member2 = \"" << state.ptrA->member2 << "\";\n";
    // 初始化ptrB
    std::cout << varName << ".ptrB = std::make_shared<ClassB>();\n";
    std::cout << varName << ".ptrB->xxx = " << state.ptrB->xxx << ";\n";
}

运行程序到目标状态时调用这个函数,把控制台输出的代码复制到test.cpp里,直接就能使用完整的StoredState实例。

3. 内存快照(仅临时同环境测试)

如果测试环境和保存状态的环境完全一致(编译器版本、系统、内存布局均相同),可以尝试直接保存对象的内存数据,但注意:你的Data包含unordered_map和shared_ptr,这类动态分配内存的成员仅靠内存快照只能保存指针地址,测试时地址无效,因此这个方法对你的场景不适用,仅作补充——如果是无动态内存的结构体,可参考:

// 保存内存快照(仅适用于无动态内存的结构体)
void saveSnapshot(const Data& state, const std::string& filename) {
    std::ofstream out(filename, std::ios::binary);
    out.write(reinterpret_cast<const char*>(&state), sizeof(state));
}
// 读取快照
void loadSnapshot(Data& state, const std::string& filename) {
    std::ifstream in(filename, std::ios::binary);
    in.read(reinterpret_cast<char*>(&state), sizeof(state));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:03:18