Boost logo

Boost Users :

Subject: [Boost-users] boost serialization: can't deserialize pointer to abstract base class where derived classes overload load_construct_data
From: Rebecca Lehman (rebecca.lehman_at_[hidden])
Date: 2013-01-08 16:27:38


I have some pointers to instances of an abstract base class. Some of the
derived classes have no default constructors. I can serialize instances of
these derived classes by overloading load_construct_data and
save_construct_data, but I always get segmentation faults when I try to
serialize the base class pointers. Saving works fine, and loading will
correctly load the instances of the derived classes, but it segfaults
before initializing the pointers. It doesn't seem to matter whether I
overload the load_construct_data and save_construct_data of the base class,
or how I register my classes and the base/derived relationship, or whether
the pointers are ordinary pointers or boost::shared_ptrs. (The details of
the segfault messages vary, but it always segfaults).

Does anyone have an example of how to serialize such pointers?

Here's a trivial example of what I'm trying to do:

class Base
{
Base() {}
public:
virtual int Apply()=0 const;
protected:
friend class boost::serialization::access;

template<class Archive>
void serialize(Archive &ar, const unsigned int version){

}
};

BOOST_ASSUME_ABSTRACT(Base);

class D1
{
public:
D1( int der_input): der_int(der_input){}
int Apply() const
{
return der_int;
}
protected:
const int & der_int;

friend class boost::serialization::access;

template<class Archive>
void serialize(Archive &ar, const unsigned int version){
     ar & boost::serialization::base_object<Base>(*this);
    // or boost::serialization::void_cast_register<D1, Base>(
    // static_cast<D1 *>(NULL),
    // static_cast<Base *>(NULL)
    // )
}

};

BOOST_CLASS_EXPORT_GUID(D1, "D1");

class D2
{
public:
D2( int der_input): der_int(der_input){}
int Apply() const
{
return 2*der_int;
}
protected:
const int der_int;

friend class boost::serialization::access;

template<class Archive>
void serialize(Archive &ar, const unsigned int version){
     ar & boost::serialization::base_object<base_class_of_T>(*this);
    // save/load class member variables
}

};

BOOST_CLASS_EXPORT_GUID(D1, "D1");

namespace boost { namespace serialization {
template<class Archive>
inline void save_construct_data(
    Archive & ar, const D1* t, const unsigned int file_version
){
    // save data required to construct instance
    ar << t->der_int;
}

template<class Archive>
inline void load_construct_data(
    Archive & ar, D1 * t, const unsigned int file_version
){
    // retrieve data from archive required to construct new instance
    int attribute;
    ar >> attribute;
    // invoke inplace constructor to initialize instance of my_class
    ::new(t)D1(attribute);
}
template<class Archive>
inline void save_construct_data(
    Archive & ar, const D2* t, const unsigned int file_version
){
    // save data required to construct instance
    ar << t->der_int;
}

template<class Archive>
inline void load_construct_data(
    Archive & ar, D2 * t, const unsigned int file_version
){
    // retrieve data from archive required to construct new instance
    int attribute;
    ar >> attribute;
    // invoke inplace constructor to initialize instance of my_class
    ::new(t)D2(attribute);
}
 }}

main(){
    ...
    ar.template register_type<D1>();
    ar.template register_type<D2>();
    std::vector<Base *> b;
    ...
    ar & b;
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net