2

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".

4

1 回答 1

7

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

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

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

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

于 2013-01-04T14:05:06.547 回答