Re: [Quantity-devel] [Echempp-devel] Clarifications about boost::serialization
Brought to you by:
berndspeiser
|
From: <ber...@t-...> - 2007-04-09 08:54:01
|
Dominik Brugger wrote: > Hello, > > yesterday it was correctly pointed out by Bernd Speiser, > that serialization of whole class hierarchies necessitates > the usage of the Factory design pattern. > > But it is not necessary to wrap up boost::serialization > with this kind of mechanism as it is already provided by > the library. > > To illustrate the serialization capabilities consider the > example program below. One important point are the > BOOST_EXPORT_GUID makros which equip each > class with a globally unique identifier. If these are > omitted the code will compile, but when reading back > the objects at runtime an exception of type "unregistered class" > will be thrown. Otherwise the objects are correctly read > back without knowing the exact type (polymorphic base*). > > Dominik Brugger Hi, yes, I am convinced in the meantime. Test with the Quantity library show thatb it indeed works in this way. (this is why I crosspost this e-mail to the quantity-devel list). One problem remains which has already been discussed several times in the boost mailing list (see, http://thread.gmane.org/gmane.comp.lib.boost.user/13244/focus=13300): automatic `registration' of template classes is not possible. This means that we explicitly have to register all necessary instances of a templare class with the serialization library. I have no clear idea in the very moment how to overcome this. One important aspect of this may also be that we have to assemble the unique identifier names for templated classes. Anyway, I will try to finalize the Quantity classes for serialization quickly. Bernd > > #include <boost/archive/xml_iarchive.hpp> > #include <boost/archive/xml_oarchive.hpp> > #include <boost/serialization/serialization.hpp> > #include <boost/serialization/base_object.hpp> > #include <boost/serialization/nvp.hpp> > #include <boost/serialization/export.hpp> > #include <fstream> > #include <iostream> > > class base > { > public: > base() : data(3.14) {} > virtual void print() > { > std::cout << "base.data " << data << std::endl; > } > private: > friend class boost::serialization::access; > template<class Archive> > void serialize(Archive & ar, const unsigned int file_version) > { > ar & BOOST_SERIALIZATION_NVP(data); > } > double data; > }; > > class derived1 : public base > { > public: > derived1() : derived1_data(42) {} > virtual void print() > { > base::print(); > std::cout << "derived1.data " << derived1_data << std::endl; > } > private: > friend class boost::serialization::access; > template<class Archive> > void serialize(Archive &ar, const unsigned int file_version) > { > ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base) > & BOOST_SERIALIZATION_NVP(derived1_data); > } > int derived1_data; > }; > > class derived2 : public base > { > public: > derived2() : derived2_data(123) {} > virtual void print() > { > base::print(); > std::cout << "derived2.data " << derived2_data << std::endl; > } > private: > friend class boost::serialization::access; > template<class Archive> > void serialize(Archive &ar, const unsigned int file_version) > { > ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base) > & BOOST_SERIALIZATION_NVP(derived2_data); > } > int derived2_data; > }; > > BOOST_CLASS_EXPORT_GUID(base, "base"); > BOOST_CLASS_EXPORT_GUID(derived1, "derived1"); > BOOST_CLASS_EXPORT_GUID(derived2, "derived2"); > > void save(const char *testfile) > { > std::ofstream os(testfile); > boost::archive::xml_oarchive oa(os); > > base *b1 = new derived1(); > base *b2 = new derived2(); > > oa << BOOST_SERIALIZATION_NVP(b1); > oa << BOOST_SERIALIZATION_NVP(b2); > > delete b1; > delete b2; > } > > void load(const char *testfile) > { > std::ifstream is(testfile); > boost::archive::xml_iarchive ia(is); > > // Note that we do not know anything about the type > // of stored objects at this point > base *b1 = NULL; > base *b2 = NULL; > > // The factory design pattern is already included in > // boost::serialization > ia >> BOOST_SERIALIZATION_NVP(b1); > ia >> BOOST_SERIALIZATION_NVP(b2); > > // Dump to stdout to check that we read back the right > // types > std::cout << "Read: "; > b1->print(); > std::cout << "Read: "; > b2->print(); > > delete b1; > delete b2; > } > > int main(int argc, char* argv[]) > { > // Note that calls to save/load can be made in > // different program runs, compilation units etc. > save("test.xml"); > load("test.xml"); > return EXIT_SUCCESS; > } -- ======================================================================= Bernd Speiser Institut für Organische Chemie Auf der Morgenstelle 18 D-72076 Tübingen Germany phone: +49-7071-2976205 (office) +49-7071-2976242 (laboratory) fax: +49-7071-295518 e-mail: ber...@un... Internet: http://www.uni-tuebingen.de/speiser ======================================================================= |