У меня есть три класса:
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);
}
Мне нужно использовать конструкторы не по умолчанию, поэтому мне нужны переопределения load / save_construct_data. Классы B и C сериализуются и десериализуются через вектор, поэтому я использую макрос BOOST_CLASS_EXPORT () (в другой части кода, я полагаю, не имеет значения). Моя проблема в том, что когда я десериализирую архив, созданный с помощью вышеуказанного кода, я получаю дубликаты указателей в моем векторе (каждый указывает на одну и ту же область в памяти) — это может быть один для базы и один для производных классов. Я нигде не могу найти, как использовать данные load / save_construct при сохранении моих объектов через указатель на базовый класс без создания дубликатов. Я потратил недели на это, и мой срок приближается очень быстро, любая помощь очень ценится 🙂
РЕДАКТИРОВАТЬ: Я должен упомянуть еще одну вещь: когда я удаляю содержимое метода «serialize» из базового класса (только содержимое, а не сам метод), после десериализации я ничего не получаю, а когда я удаляю части с помощью «base_object», архив выдает исключение » незарегистрированный актерский состав «.
Руководство по повышению не очень хорошо сделано, я нашел свой ответ в разделе «Сериализация шаблонов» 🙂
Мне просто нужно было оставить пустым метод serialize базового класса, а в производных классах поставить методы сериализации
boost::serialization::void_cast_register<derived, base>();
Для дальнейшего использования — теперь все работает нормально 🙂
Других решений пока нет …