I recently came across something really puzzling with regards to serialization using C++ Boost library. As far I as searched for it, I could not find anything relevant information. So I was thinking that maybe somebody can enlighten me... or at least this will be referenced and may become useful to anyone later.
In essence : in C++, serializing an object with Boost serialization library does not produce the same resulting file if you serialize using a pointer or using a value. Here is a snippet of code to reproduce it
#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 ;
}
On my machine, both resulting files are different.
val.animal
22 serialization::archive 19 1 0
ptr.animal
22 serialization::archive 19 0 1 0
There is an extra 0 in the ptr.animal file.
Consequently, you can get into trouble when trying to reload the data from the files if you mix value and pointer serialization and de-serialization. This issue actually kept me busy a few days...
I was wondering whether there was an explanation for this? Or maybe am I simply doing things terribly wrong here?