Boost logo

Boost Users :

Subject: [Boost-users] Boost Serialize and derived classes
From: John Yamokoski (yamokosk_at_[hidden])
Date: 2008-09-16 17:12:13


I can't seem to figure out if what I want is possible. I am using the
Boost Serialization library to save the state of my program. I have a
manager-type class which holds onto pointers of a base class. The
Boost Serialization website has a lot to say about base and derived
classes. In a tutorial they show one way to deal with them. But it
assumes a priori knowledge of the derived classes:

class bus_route
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
    typedef bus_stop * bus_stop_pointer;
    std::list<bus_stop_pointer> stops;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // in this program, these classes are never serialized
directly but rather
        // through a pointer to the base class bus_stop. So we need a way to be
        // sure that the archive contains information about these
derived classes.
        //ar.template register_type<bus_stop_corner>();
        ar.register_type(static_cast<bus_stop_corner *>(NULL)); //
TYPES KNOWN A PRIORI
        //ar.template register_type<bus_stop_destination>();
        ar.register_type(static_cast<bus_stop_destination *>(NULL));
// TYPES KNOWN A PRIORI
        // serialization of stl collections is already defined
        // in the header
        ar & BOOST_SERIALIZATION_NVP(stops);
    }
public:
    bus_route(){}
    void append(bus_stop *_bs)
    {
        stops.insert(stops.end(), _bs);
    }
};

In my code, however, I don't know exactly what the derived classes
might be. The derived objects are created and passed back to my
manager class through the base pointer.

One option I was considering was that when plugins register with the
program, they would have to also register the derived class names with
the archive. How this would actually be implemented, I have no idea.
Can an archive object be created independently from the Serialization
library, modified and then sent back to Serialization?

Here is a simple test case I am working on, but I just can't get it to
write out the derived classes to file:

class base
{
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int file_version)
        {
                ar & BOOST_SERIALIZATION_NVP(val);
        }
public:
        base() : val(0.0) {}
        base(double b) : val(b) {}
        double val;
};

class derived : public base
{
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int file_version)
        {
                boost::serialization::void_cast_register<derived,
base>(static_cast<derived *>(NULL),static_cast<base *>(NULL));
                ar & BOOST_SERIALIZATION_NVP(val);
        }
public:
        derived() : base(0.0), val(0) {}
        derived(int a, double b) : base(b), val(a) {}
        int val;
};

BOOST_CLASS_EXPORT_GUID(derived, "derived");

class manager
{
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int file_version) {
                ar & BOOST_SERIALIZATION_NVP(objs);
        }
public:
        std::list<base*> objs;
};

void main()
{
        manager mgr;

        // Creat some data to save
        derived *d1, *d2, *d3, *d4;
        d1 = new derived(1, 1.0);
        d2 = new derived(2, 3.0);

        mgr.objs.push_back( d1 );
        mgr.objs.push_back( d2 );

        {
                std::ofstream ofs("out.xml");
                assert(ofs.good());
                boost::archive::xml_oarchive oa(ofs);
                oa << BOOST_SERIALIZATION_NVP(mgr);
                ofs.close();
        }

        manager new_mgr;

        {
                std::ifstream ifs("out.xml");
                assert(ifs.good());
                boost::archive::xml_iarchive ia(ifs);
                ia >> BOOST_SERIALIZATION_NVP(new_mgr);
                ifs.close();
        }

        {
                std::ofstream ofs("check.xml");
                assert(ofs.good());
                boost::archive::xml_oarchive oa(ofs);
                oa << BOOST_SERIALIZATION_NVP(new_mgr);
                ofs.close();
        }

        delete d1, d2;
}

I apologize if this commonly asked but I was just looking for some
insight as to the best approach.

J.D.


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