我正在尝试使用 boost 序列化库来序列化一个类。序列化工作得很好,但是当我尝试读取写入文件的内容时,出现“输入错误”异常。
我阅读了 boost 序列化库的文档并提出了 (1) 了解如何使用非默认构造函数序列化和反序列化类。我试图尽可能接近文档中的示例。
我尝试从 Book 类的序列化方法(文档示例中所做的)中删除
ar & name
,这也导致了输入流错误。
调试时,我发现异常在 load_primitive` 函数的
load _access
类中抛出。
#include <fstream>
#include <filesystem>
#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
class Book
{
private:
std::string name;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & name;
}
public:
Book(std::string name): name(name) {}
};
namespace boost {
namespace serialization {
template<class Archive>
inline void save_construct_data(Archive& ar, Book* book, const unsigned int file_version)
{
ar << book->name;
}
template<class Archive>
inline void load_construct_data(Archive& ar, Book* book, const unsigned int file_version)
{
std::string name;
ar >> name;
::new(book)Book(name);
}
}
}
int main()
{
Book book("Harry Potter");
std::ofstream ofs("Book.txt");
boost::archive::text_oarchive oa(ofs);
oa << &book;
ofs.close();
Book* read;
std::ifstream ifs("Book.txt", std::ios::binary);
boost::archive::text_iarchive ia(ifs);
ia >> read;
ifs.close();
}
我收到以下错误
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): input stream error
提前感谢任何遮阳篷。 菲利克斯
save_construct_data()
和 load_construct_data()
应该一起工作,但在您的代码中 save_construct_data()
永远不会被调用。发生这种情况是因为它的签名不正确:Book*
应该是const Book*
。您会收到流错误,因为序列化和反序列化彼此不一致 - 序列化写入 Book::name
一次,但反序列化尝试读取它两次(您尝试在 Book::name
和 中序列化/反序列化
save_construct_data()
两次) serialize()
)。
完整的工作示例(
main()
未更改):
class Book
{
friend class boost::serialization::access;
private:
std::string name;
template<class Archive>
void serialize(Archive&, unsigned int) { }
template<class Archive>
friend void save_construct_data(Archive& ar, const Book* book, unsigned int) {
ar << book->name;
}
template<class Archive>
friend void load_construct_data(Archive& ar, Book* book, unsigned int) {
std::string name;
ar >> name;
::new(book) Book(std::move(name));
}
public:
Book(std::string name): name(std::move(name)) { }
};
我在类中将
save_construct_data()
声明为 friend
以简化代码。由于某种原因,如果它定义在 boost::serialization
命名空间中,除了与 friend
友好之外,您还需要为该函数添加 boost::serialization::access
声明。文档中没有提到这一点,但如果没有 friend
声明,代码将无法编译。