I have a pretty simple class, that I want to serialize with boost::serialize.
class Entity {
private:
ObjectType objectType;
public:
Entity(ObjectType t = tA) { objectType = t; }
public:
~Entity() {}
private:
friend class boost::serialization::access;
template <typename Archive>
friend void boost::serialization::serialize(Archive& ar, Entity& o, const unsigned int version);
};
}
ObjectType is an enum:
typedef enum ObjectType {
tA,
tB,
...
tZ
}
And the serialization function is the following:
template<class Archive>
void serialize(Archive & ar, Entity & o, const unsigned int version)
{
ar & o.objectType;
}
Saving and loading are performed with the following functions:
void saveObject2File(const Entity &o, const char * filename) {
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa & o;
}
Entity * loadObjectFromFile(const char * filename) {
std::ifstream ifs(filename);
boost::archive::text_iarchive ia(ifs);
Object * o;
ia & o;
return o;
}
When I serialize to a file, the following text is written into it, where the number 17 is the integer value stored in the objectType variable.
22 serialization::archive 10 0 0 17
However, when I read this file, the value 17 is received by the serialize
method as the version
parameter, and the objectType
is assigned with a wrong value (o.objectType = -858993460)
.
If I manually change the class version BOOST_CLASS_VERSION(Entity, 111);
before saving and loading, I get a runtime-exception. Writing works with the 111 version number, but reading the file fails.
Strangely enough, if I use xml archives, the problem does not occur. The problem is the same if I opt to serialize an integer instead of the enum. It seems as if the text_iarchive is looking for (and reading) an extra parameter, which is not provided by the text_oarchive, therefore 17 is read as the version number.
I am using Boost 1.55 and Visual Studio 2013.
Any help is welcome.
You made a standard mistake here: you serialize an OBJECT (of type Entity) but you try to deserialize A POINTER. You should make it consistent (OBJECT-OBJECT or POINTER-POINTER).
It also seems you did not tell the whole story and your class Entity is a base of some class hierarchy. In this case you likely should use serialization of POINTERs; besides you will need methods described here: Boost Serialization: pointer conainer to <BASE> contains various of DERIVED objects