C++;:如何在不使用库的情况下序列化/反序列化对象? 我试图理解C++中序列化/反序列化是如何工作的,而不需要使用库。我从简单的对象开始,但是当反序列化一个向量时,我发现,如果不先写出向量的大小,我就无法得到它。此外,我不知道应该选择哪种文件格式,因为,若向量大小之前存在数字,我就无法正确读取。此外,我想用类和映射容器来实现这一点。我的任务是序列化/反序列化对象,如下所示: PersonInfo { unsigned int age_; string name_; enum { undef, man, woman } sex_; } Person : PersonInfo { vector<Person> children_; map<string, PersonInfo> addrBook_; } vector<PersonInfo> vecPersonInfo; vecPersonInfo.push_back(*personInfo); vecPersonInfo.push_back(*oneMorePersonInfo); ofstream file("file", ios::out | ios::binary); if (!file) { cout<<"can not open file"; } else { vector<PersonInfo>::const_iterator iterator = vecPersonInfo.begin(); for (; iterator != vecPersonInfo.end(); iterator++) { file<<*iterator; } PersonInfo { 无符号整数; 字符串名称; 枚举{未定义,男人,女人}性; } 个人:PersonInfo { 媒介儿童; 映射addrBook; }

C++;:如何在不使用库的情况下序列化/反序列化对象? 我试图理解C++中序列化/反序列化是如何工作的,而不需要使用库。我从简单的对象开始,但是当反序列化一个向量时,我发现,如果不先写出向量的大小,我就无法得到它。此外,我不知道应该选择哪种文件格式,因为,若向量大小之前存在数字,我就无法正确读取。此外,我想用类和映射容器来实现这一点。我的任务是序列化/反序列化对象,如下所示: PersonInfo { unsigned int age_; string name_; enum { undef, man, woman } sex_; } Person : PersonInfo { vector<Person> children_; map<string, PersonInfo> addrBook_; } vector<PersonInfo> vecPersonInfo; vecPersonInfo.push_back(*personInfo); vecPersonInfo.push_back(*oneMorePersonInfo); ofstream file("file", ios::out | ios::binary); if (!file) { cout<<"can not open file"; } else { vector<PersonInfo>::const_iterator iterator = vecPersonInfo.begin(); for (; iterator != vecPersonInfo.end(); iterator++) { file<<*iterator; } PersonInfo { 无符号整数; 字符串名称; 枚举{未定义,男人,女人}性; } 个人:PersonInfo { 媒介儿童; 映射addrBook; },c++,serialization,deserialization,C++,Serialization,Deserialization,目前我知道如何序列化以下简单对象: PersonInfo { unsigned int age_; string name_; enum { undef, man, woman } sex_; } Person : PersonInfo { vector<Person> children_; map<string, PersonInfo> addrBook_; } vector<PersonInf

目前我知道如何序列化以下简单对象:

PersonInfo
{
    unsigned int    age_;
    string name_;
    enum { undef, man, woman } sex_;
}

Person : PersonInfo 
{
    vector<Person>      children_;
    map<string, PersonInfo>     addrBook_;
}
vector<PersonInfo> vecPersonInfo;
vecPersonInfo.push_back(*personInfo);
vecPersonInfo.push_back(*oneMorePersonInfo);

ofstream file("file", ios::out | ios::binary);
if (!file) {
    cout<<"can not open file";
} else {
    vector<PersonInfo>::const_iterator iterator = vecPersonInfo.begin();
    for (; iterator != vecPersonInfo.end(); iterator++) {
        file<<*iterator;
    }
vectorVecPersonInfo;
vecPersonInfo.向后推(*personInfo);
vecPersonInfo.将_向后推(*oneMorePersonInfo);
流文件(“文件”,ios::out | ios::binary);
如果(!文件){

cout一种模式是实现一个抽象类,该类定义用于序列化的函数,该类定义进入序列化程序的内容和输出的内容。例如:

class Serializable
{
public:
    Serializable(){}
    virtual ~Serializable(){}

    virtual void serialize(std::ostream& stream) = 0;
    virtual void deserialize(std::istream& stream) = 0;
};
然后,为要序列化的类/结构实现可序列化接口:

struct PersonInfo : public Serializable // Yes! It's possible
{
    unsigned int age_;
    string name_;
    enum { undef, man, woman } sex_;

    virtual void serialize(std::ostream& stream)
    {
        // Serialization code
        stream << age_ << name_ << sex_;
    }

    virtual void deserialize(std::istream& stream)
    {
        // Deserialization code
        stream >> age_ >> name_ >> sex_;
    }
};
struct PersonInfo:public Serializable//Yes!这是可能的
{
无符号整数;
字符串名称;
枚举{未定义,男人,女人}性;
虚拟空序列化(std::ostream和stream)
{
//序列化代码
流>姓名>性别;
}
};
休息我相信你知道。这里有几个障碍需要克服,你可以在空闲时完成:

  • 当您向流中写入一个包含空格的字符串并尝试将其读回时,您将只得到其中的一部分,而该字符串的其余部分将“破坏”此后读取的值
  • 如何编程使其跨平台(little endian vs big endian)
  • 在反序列化时,程序如何自动检测要创建的类
  • 线索:

  • 使用自定义序列化程序,该序列化程序具有写入bool、int、float、string等函数
  • 使用字符串表示要序列化的对象类型,并在反序列化时使用factory创建该对象的实例
  • 使用预定义宏确定编译代码的平台
  • 始终以固定尾端编写文件,并使使用其他尾端的平台适应该尾端

  • 最基本的形式是定义一个“可序列化”接口(抽象类),该接口定义虚拟读/写方法。您还可以定义一个“流”接口,该接口为基本基元类型(例如读取/写入整数、浮点、字节、字符、寻道/重置)以及某些复合类型提供通用API在流上运行的数组(例如字符串、向量等的数组)。如果适合你,你可以使用C++ IoSokes。 您还需要一些id系统,以便工厂在加载/反序列化时创建相应的类,并在序列化复杂类型时进行引用,以便在必要时使用适当的结构/长度信息对每个逻辑部分进行标记/标题

    然后,您可以为每种媒体(如文本文件、二进制文件、内存、网络等)创建具体的流类

    然后,您希望序列化的每个类都必须继承可序列化接口并实现细节(如果是复合/复杂类,则递归地利用为其他类型定义的可序列化接口)

    当然,这是一种添加序列化(必须修改参与的类)的幼稚且“侵入性”的方式。然后,您可以使用模板或预处理器技巧来降低其侵入性。请参阅Boost或protocol buffers,或任何其他库,了解这在代码中的表现


    你真的确定要自己动手吗?它会变得非常混乱,特别是当你有指针,对象之间的指针(包括循环)时,在加载/反序列化正确用于当前运行之前,您还需要在某个时候对其进行修复/翻译。

    为什么您不能使用库?@KillianDS可能想学习。正如他所说的,他正试图理解如何完成。完全正确。这只是为了教育目的。@redx或者他想避免使用库,因为它们很难使用分发,或者这是作业,或者…,这就是为什么我问序列化问题(没有库)在所有语言中都完全相同:您需要知道您正在反序列化什么,或者在序列化时记下它。然后根据您的需要选择最合适的格式,并为此编写解析器/生成器……这将失败,因为您没有添加分隔符、sex(枚举值)将作为名称的一部分读取。此外,如果名称有多个单词,则只会读取其中的第一个…问题比提供的简单解决方案要复杂一些。