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 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();
ar.register_type(static_cast(NULL)); //
TYPES KNOWN A PRIORI
//ar.template register_type();
ar.register_type(static_cast(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(static_cast(NULL),static_cast(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 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.