序列化包含std :: string的类

iwa*_*now 13 c++ serialization binaryfiles

我不是c ++专家,但过去我曾多次将事情序列化.不幸的是,这次我正在尝试序列化一个包含std :: string的类,我理解这很像序列化指针.

我可以将类写出来并再次读回来.所有int字段都很好,但是std :: string字段给出了"地址越界"错误,大概是因为它指向不再存在的数据.

这有一个标准的解决方法吗?我不想回到char数组,但至少我知道它们在这种情况下工作.如有必要,我可以提供代码,但我希望我已经很好地解释了我的问题.

我通过将类转换为char*并使用fstream将其写入文件来进行序列化.阅读当然恰恰相反.

Moo*_*uck 11

我通过将类转换为char*并使用fstream将其写入文件来进行序列化.阅读当然恰恰相反.

不幸的是,这只有在没有涉及指针的情况下才有效.你可能想给你的类void MyClass::serialize(std::ostream)void MyClass::deserialize(std::ifstream),并呼吁那些.对于这种情况,你想要的

std::ostream& MyClass::serialize(std::ostream &out) const {
    out << height;
    out << ',' //number seperator
    out << width;
    out << ',' //number seperator
    out << name.size(); //serialize size of string
    out << ',' //number seperator
    out << name; //serialize characters of string
    return out;
}
std::istream& MyClass::deserialize(std::istream &in) {
    if (in) {
        int len=0;
        char comma;
        in >> height;
        in >> comma; //read in the seperator
        in >> width;
        in >> comma; //read in the seperator
        in >> len;  //deserialize size of string
        in >> comma; //read in the seperator
        if (in && len) {
            std::vector<char> tmp(len);
            in.read(tmp.data() , len); //deserialize characters of string
            name.assign(tmp.data(), len);
        }
    }
    return in;
}
Run Code Online (Sandbox Code Playgroud)

您可能还希望重载流操作符以便于使用.

std::ostream &operator<<(std::ostream& out, const MyClass &obj)
{obj.serialize(out); return out;}
std::istream &operator>>(std::istream& in, MyClass &obj)
{obj.deserialize(in); return in;}
Run Code Online (Sandbox Code Playgroud)


Ant*_*tti 10

简单地将对象的二进制内容写入文件不仅是不可移植的,而且正如您所知,它不适用于指针数据.您基本上有两个选择:要么编写一个真正的序列化库,它通过例如使用c_str()将实际字符串输出到文件来正确处理std :: strings ,或者使用优秀的boost序列化库.如果可能的话,我建议使用后者,然后你可以使用这样的简单代码进行序列化:

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/string.hpp>

class A {
    private:
        std::string s;
    public:
        template<class Archive>
        void serialize(Archive& ar, const unsigned int version)
        {
            ar & s;
        }
};
Run Code Online (Sandbox Code Playgroud)

这里,该函数serialize用于序列化和反序列化数据,具体取决于您调用它的方式.有关更多信息,请参阅文档.