c++ Boost指针vs值序列化



我最近在使用c++ Boost库进行序列化时遇到了一些非常令人困惑的问题。就我搜索而言,我找不到任何相关的信息。所以我在想也许有人能开导我…或者至少这将被引用,并可能在以后对任何人有用。

本质上:在c++中,使用Boost序列化库序列化对象不会产生相同的结果文件,如果您使用指针或使用值进行序列化。下面是复制它的代码片段

#include <string>
#include <fstream>
#include <boost/archive/text_oarchive.hpp>      // boost::archive::text_oarchive
#include <boost/archive/text_iarchive.hpp>      // boost::archive::text_iarchive
// we are getting into classics here
class animal
{
public:

animal() = default;

animal(int legs) 
: legs_(legs) 
{ ; }

int legs() const
{ return legs_; }
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{   if(version < 1)
{ ; }
ar & legs_;
}
int legs_;
} ;
// saves using pointer
void save_ptr(const std::string& path,
const animal* animal)
{   
std::ofstream f_out(path) ;
boost::archive::text_oarchive arch_out(f_out) ;

arch_out << animal ;
f_out.close() ;
}

// save using value
void save_val(const std::string& path,
animal animal)
{   
std::ofstream f_out(path) ;
boost::archive::text_oarchive arch_out(f_out) ;

arch_out << animal ;
f_out.close() ;
}

int main()
{
std::string path_out_val("val.animal") ;
std::string path_out_ptr("ptr.animal") ;
animal animal ;
save_val(path_out_val,  animal) ;
save_ptr(path_out_ptr, &animal) ;
return 0 ;
}

在我的机器上,两个结果文件是不同的。

val.animal

22 serialization::archive 19 1 0

ptr.animal

22 serialization::archive 19 0 1 0

ptr中有一个额外的0。动物文件。

因此,如果您混合了值和指针序列化和反序列化,则在尝试从文件中重新加载数据时可能会遇到麻烦。这件事让我忙了好几天……

我想知道这是否有一个解释?或许我只是做错了什么?

是的。你做错了。

指针不是值。它们需要动态分配,需要对象跟踪。

(反)序列化所需的操作是值序列化的超集。从某种意义上说,T*被序列化为*T(如果不是nullptr)和额外的元数据来处理指针和任何动态转换。

  • 指针序列化记录在这里https://www.boost.org/doc/libs/1_79_0/libs/serialization/doc/tutorial.html#pointers
  • 对象跟踪记录在这里:https://www.boost.org/doc/libs/1_79_0/libs/serialization/doc/special.html#objecttracking

作为旁注,在归档完成之前不要关闭文件流。遗憾的是,我知道执行它的唯一方法就是运行析构函数。只需删除多余的关闭符:

// saves using pointer
void save_ptr(const std::string &path, const animal *animal) {
std::ofstream f_out(path);
boost::archive::text_oarchive arch_out(f_out);
arch_out << animal;
}
// save using value
void save_val(const std::string &path, animal animal) {
std::ofstream f_out(path);
boost::archive::text_oarchive arch_out(f_out);
arch_out << animal;
}

相关内容

  • 没有找到相关文章

最新更新