
I have spent several hours combing the documentation and archives, but can't seem to find an answer to my problem. I have an abstract base class, Operation with a pure virtual function 'double value() = 0'. I derive a class, BinaryOperation from Operation. It takes as arguments an operation type (+, -, *, /) and two Operation pointers --- one for the left operand, one for the right. It stores these two pointers internally and uses them when the value() method is invoked. I derive two more classes from Operation, trivial, made-up, useless ones. One is called IncrementOperation, one is called DecrementOperation. I can save to an XML archive properly, but when I try to restore, it core dumps. I am running gcc-3.2. I have tried everything I can think of, but am stuck. I have tried using polymorphic_xml_iarchive (and corresponding output version), but it still fails. The first few stack frames from GDB are: #0 0x0808897f in ?? () #1 0x08052f7d in boost::archive::detail::basic_iarchive::load_pointer(void*&, boost::archive::detail::basic_pointer_iserializer const*, boost::archive::detail::basic_pointer_iserializer const* (*)(boost::serialization::extended_type_info const&)) () #2 0x0804c78a in boost::archive::detail::load_pointer_type<boost::archive::xml_iarchive, Operation*>::invoke(boost::archive::xml_iarchive&, Operation*&) ( ar=@0xbffff0e0, t=@0xbffff330) at /usr/local/include/boost-1_32/boost/archive/detail/iserializer.hpp:450 #3 0x0804c51a in load<boost::archive::xml_iarchive, Operation*> ( ar=@0xbffff0e0, t=@0xbffff330) at /usr/local/include/boost-1_32/boost/archive/detail/iserializer.hpp:529 Following my sig, I've posted the xml input file that is generated by the save, and then following that, the C++ code (fairly short). It is failing on the following line: ia & BOOST_SERIALIZATION_NVP(t); Any help would be appreciated. Thanks. Bill <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="3"> <t class_id="1" class_name="BinaryOperation" tracking_level="1" version="0" object_id="_0"> <Operation class_id="0" tracking_level="1" version="0" object_id="_1"></Operation> <_op>42</_op> <_left_operand class_id_reference="1" object_id="_2"> <Operation object_id="_3"></Operation> <_op>43</_op> <_left_operand class_id="2" class_name="IncrementOperation" tracking_level="1" version="0" object_id="_4"> <Operation object_id="_5"></Operation> <_init>33</_init> </_left_operand> <_right_operand class_id="3" class_name="DecrementOperation" tracking_level="1" version="0" object_id="_6"> <Operation object_id="_7"></Operation> <_init>333</_init> </_right_operand> </_left_operand> <_right_operand class_id_reference="1" object_id="_8"> <Operation object_id="_9"></Operation> <_op>45</_op> <_left_operand class_id_reference="3" object_id="_10"> <Operation object_id="_11"></Operation> <_init>444</_init> </_left_operand> <_right_operand class_id_reference="2" object_id="_12"> <Operation object_id="_13"></Operation> <_init>44</_init> </_right_operand> </_right_operand> </t> </boost_serialization> #include <string> #include <iomanip> #include <iostream> #include <fstream> #include <stdexcept> #include <boost/serialization/nvp.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> //#include <boost/archive/polymorphic_xml_iarchive.hpp> //#include <boost/archive/polymorphic_xml_oarchive.hpp> #include <boost/serialization/export.hpp> class Operation { public: Operation() { } virtual ~Operation() { } virtual double value() = 0; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /* file_version */){ } }; BOOST_IS_ABSTRACT(Operation); class BinaryOperation: public Operation { public: BinaryOperation() : _op(' '), _left_operand(0), _right_operand(0) { } BinaryOperation(char op, Operation* left_operand, Operation* right_operand) : _op(op), _left_operand(left_operand), _right_operand(right_operand) { } virtual ~BinaryOperation() { } virtual double value() { switch (_op) { case '+': return _left_operand->value() + _right_operand->value(); break; case '-': return _left_operand->value() - _right_operand->value(); break; case '*': return _left_operand->value() * _right_operand->value(); break; case '/': return _left_operand->value() / _right_operand->value(); break; } } protected: char _op; Operation* _left_operand; Operation* _right_operand; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /* file_version */){ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Operation) & BOOST_SERIALIZATION_NVP(_op) & BOOST_SERIALIZATION_NVP(_left_operand) & BOOST_SERIALIZATION_NVP(_right_operand); } }; BOOST_CLASS_EXPORT_GUID(BinaryOperation, "BinaryOperation"); class IncrementOperation : public Operation { public: IncrementOperation() : _init(0) { } IncrementOperation(double init) : _init(init) { } virtual double value() { return _init++; } protected: double _init; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /* file_version */){ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Operation) & BOOST_SERIALIZATION_NVP(_init); } }; BOOST_CLASS_EXPORT_GUID(IncrementOperation, "IncrementOperation"); class DecrementOperation : public Operation { public: DecrementOperation() : _init(0) { } DecrementOperation(double init) : _init(init) { } virtual double value() { return _init--; } protected: double _init; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /* file_version */){ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Operation) & BOOST_SERIALIZATION_NVP(_init); } }; BOOST_CLASS_EXPORT_GUID(DecrementOperation, "DecrementOperation"); void save_Operation(const Operation* t) { std::ofstream ofs("operation.xml"); assert(ofs.good()); boost::archive::xml_oarchive oa(ofs); //boost::archive::polymorphic_xml_oarchive oa(ofs); oa & BOOST_SERIALIZATION_NVP(t); } void restore_Operation(Operation*& t) { std::ifstream ifs("operation.xml"); if (!ifs.good()) { throw std::runtime_error("No input archive file"); } boost::archive::xml_iarchive ia(ifs); //boost::archive::polymorphic_xml_iarchive ia(ifs); std::cout << "Reading ...\n"; ia & BOOST_SERIALIZATION_NVP(t); std::cout << "Done reading ...\n"; } int main(int, char *[]) { try { Operation* a = new BinaryOperation('+', new IncrementOperation(33), new DecrementOperation(333)); Operation* b = new BinaryOperation('-', new DecrementOperation(444), new IncrementOperation(44)); Operation* c = new BinaryOperation('*', a, b); save_Operation(c); Operation* new_c; std::cout << "Restoring\n"; restore_Operation(new_c); } catch (std::exception e) { std::cerr << e.what() << '\n'; return 1; } return 0; }