увеличить load_construct_data и сериализовать производные классы через указатель на базу

У меня есть три класса:

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», архив выдает исключение » незарегистрированный актерский состав «.

2

Решение

Руководство по повышению не очень хорошо сделано, я нашел свой ответ в разделе «Сериализация шаблонов» 🙂

Мне просто нужно было оставить пустым метод serialize базового класса, а в производных классах поставить методы сериализации

boost::serialization::void_cast_register<derived, base>();

Для дальнейшего использования — теперь все работает нормально 🙂

7

Другие решения

Других решений пока нет …