boost的load_construct_data并通过指向base的序列化派生类

时间:2013-01-03 20:07:21

标签: c++ derived boost-serialization

我有三个班级:

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()(在代码的另一部分,我认为不相关)。我的问题是,当我用上面的代码反序列化一个存档时,我在向量中得到了重复的指针(每个都指向内存中的相同区域) - 它可能是一个用于base而一个用于派生clas。我无法找到任何地方,如何使用load / save_construct数据,当通过指向基类的指针保存我的对象而不重复。我花了几个星期的时间,我的截止日期很快到了,任何帮助都非常感激:)

编辑:我还要提一件事:当我从基类中删除“serialize”方法的内容(只有内容,而不是方法本身)时,反序列化后我什么都没得到,当我使用“base_object”删除部件,archive会抛出异常“unregistered void cast”。

1 个答案:

答案 0 :(得分:7)

Boost手册不是很好,我在“模板序列化”部分找到了答案:)

我只需要将基类的serialize方法留空,并在派生类中放置序列化方法

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

供将来参考 - 现在一切正常:)