views:

288

answers:

2

Hi, i would like to serialize a class with an attribute as a list of pointers on a generic class

This is the parent class from which the generic class derives :

class Base{

    public :

        friend class boost::serialization::access;

        virtual ~Base(){}

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

        virtual string Getid() = 0 ;

};

The generic class :

template<typename T>
class GenericBase : public Base
{
    public:

        friend class boost::serialization::access;

        GenericBase<T>(string id){}
        ~GenericBase(){}

        string id;

        vector<T> data

        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & boost::serialization::base_object<Base>(*this);
            ar & BOOST_SERIALIZATION_NVP( id);
            ar & BOOST_SERIALIZATION_NVP( data);

        }

        string Getid() { return id; }

};

The class i want to serialize

class Use
{
    public:

        friend class boost::serialization::access;

        int Id;

        map<string, Base*> BaseDatas;

        Use();
        ~Use();

};

So, after reading the boost serialization doc (http://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#derivedpointers), i tried this in the serialization code :

main(){

   Use u = Use();

   std::ofstream ofs(filename, ios::binary);

   // save data to archive

   boost::archive::binary_oarchive oa(ofs);

   oa.template register_type<GenericBase<Type1> >();
   oa.template register_type<GenericBase<Type2> >();
   oa.template register_type<GenericBase<Type3> >();

   oa<<u;

}

I got a message,

error: 'template' (as a disambiguator) is only allowed within templates

, so i replaced

oa.template register_type >();

by

oa.register_type();

it worked and i have been able to save in text and in binary (i checked the datas)

for loading now, i just used these lines :

main(){

    Use u;

    std::ifstream ifs(filename, ios::binary);

    // load data

    ia.register_type<GenericBase<Type1> >();

    boost::archive::binary_iarchive ia(ifs);

    ia>>u;

}

it threw me an error :

error: no matching function for call to 'GenericBase::GenericBase()'

someone told me i had to override 2 methods save and load like in this sample http://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#constructors

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

template<class Archive>
inline void load_construct_data(
    Archive & ar, my_class * 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)my_class(attribute);
    }
}} // namespace ...

but where do I have to define them ? In declaration of the Use class ? And how do I deal with the member

map<string, Base*> BaseDatas;

?

thanks for your help ;)

A: 

but where do I have to define them ?

You can define them in any of your headers

And how do I deal with the member...

I think you can get boost to track pointers using BOOST_CLASS_TRACKING ...

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/special.html#objecttracking

"You can define them in any of your headers"but in which class haeder? Use, Base, GenericBase ?"I think you can get boost to track pointers using BOOST_CLASS_TRACKING ..."what's the point ? the problem is not a single pointer but a map of pointers; how do i deal with this map of pointers in the load_construct_data method ?
I put mine into a separate header called "serialisation.hpp"... that might be a good place, then include that in the other class headers?The map can be dealt with using the built in serialisation of some stl containers: #include "boost/serialization/map.hpp"
+1  A: 

Hi,

It is easier to comment if you provide a working (cut-and-paste) example of your failing code, with some dummy data ...

But I try to answer anyway ...

Boost.serialisation is trying to call GenericBases default constructor, but fails since you don't provide it. Boost.serialisation first creates your object (or tries now), THEN reads the file and sets the variables.

You could try declaring a protected default constructor, which boost should have access to through access.

christoff