I have three classes:
class A
{
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & this->id & this->somefield;
}
protected:
A() {} // just for boost, normally I create this class with non-default constructor
int id;
Sometype somefield;
public:
A(unsigned int id);
// blah blah, also some virtual methods
};
// _____________________ CLASS B
class B : public A
{
private:
friend class boost::serialization::access;
template<class Archive> inline friend void load_construct_data(Archive &ar, B *t, const unsigned int file_version);
template<class Archive> inline friend void save_construct_data(Archive &ar, const B *t, const unsigned int file_version);
B(unsigned int id, Sometype somefield, Sometype some_new_field1, Sometype some_new_field2);
Sometype some_new_field1;
Sometype some_new_field2;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::base_object<A>(*this);
}
public:
// blah blah, also virtual methods
};
template<class Archive>
inline void save_construct_data(
Archive & ar, const B * t, const unsigned int file_version
){
ar << t->id << t->somefield << t->some_new_field1 << t->some_new_field2;
}
template<class Archive>
inline void load_construct_data(
Archive & ar, B * t, const unsigned int file_version
){
unsigned int _id;
Sometype _somefield;
Sometype _some_new_field1;
Sometype _some_new_field2;
ar >> _id >> _somefield >> _some_new_field1 >> _some_new_field2;
::new(t)B(_id, _somefield, _some_new_field1, _some_new_field2);
}
// _____________________ CLASS C
class C : public A
{
private:
friend class boost::serialization::access;
template<class Archive> inline friend void load_construct_data(Archive &ar, C *t, const unsigned int file_version);
template<class Archive> inline friend void save_construct_data(Archive &ar, const C *t, const unsigned int file_version);
C(unsigned int id, Sometype somefield, Sometype some_new_field3, Sometype some_new_field4);
Sometype some_new_field3;
Sometype some_new_field4;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::base_object<A>(*this);
}
public:
// blah blah, also virtual methods
};
template<class Archive>
inline void save_construct_data(
Archive & ar, const C * t, const unsigned int file_version
){
ar << t->id << t->somefield << t->some_new_field3 << t->some_new_field4;
}
template<class Archive>
inline void load_construct_data(
Archive & ar, C * t, const unsigned int file_version
){
unsigned int _id;
Sometype _somefield;
Sometype _some_new_field3;
Sometype _some_new_field4;
ar >> _id >> _somefield >> _some_new_field3 >> _some_new_field4;
::new(t)C(_id, _somefield, _some_new_field3, _some_new_field4);
}
I need to use non-default constructors, so I need load/save_construct_data overrides. Classes B and C are serialized and deserialized through vector, hence I use the macro BOOST_CLASS_EXPORT() (in another part of code, irrelevant, I suppose). My problem is, when I deserialize an archive made with above code, I get duplicate pointers in my vector (each pointing at the same area in memory) - it might be one for base and one for derived clas. I can't find anywhere, how to use load/save_construct data, when saving my objects through a pointer to base class without making duplicates. I spent weeks on this and my deadline is approaching very quickly, any help greatly appreciated :)
EDIT: I should mention one more thing: when I remove contents of "serialize" method from base class (only contents, not the method itself), after deserialization I get nothing, and when I remove parts with "base_object", archive throws an exception "unregistered void cast".