私には3つのクラスがあります:
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データの使用方法をどこにも見つけることができません。私はこれに何週間も費やしました、そして私の締め切りは非常に速く近づいています、どんな助けも大いに感謝します:)
編集:もう1つ言及する必要があります:「serialize」メソッドのコンテンツを基本クラスから削除すると(メソッド自体ではなくコンテンツのみ)、逆シリアル化した後は何も取得せず、「base_object」を含むパーツを削除すると、アーカイブは例外「未登録のボイドキャスト」。