#include #include #include #include #include struct Base { Base() : base(43) { } virtual ~Base() { } virtual void print() { std::cout << "base: " << base << std::endl; } int base; template void serialize(Archive & ar, const unsigned int version) { ar & base; } }; struct Derived : Base { Derived() { } Derived(int n) : size(n) { while(--n > 0) derived[n] = n; } virtual void print() { std::cout << "size: " << size << std::endl << "derived: "; for(int i = 0; i < size; i++) std::cout << derived[i] << " "; std::cout << std::endl; } void *operator new(size_t size, size_t extra) { return ::operator new(size + sizeof(int) * extra); } void operator delete(void *p) { ::operator delete(p); } int size; int derived[0]; template void serialize(Archive & ar, const unsigned int version) { if(Archive::is_saving::value) ar & size; ar & boost::serialization::base_object(*this); for(int i = 0; i < size; ++i) ar & derived[i]; } }; namespace boost { namespace archive { namespace detail { template class pointer_iserializer : public archive_pointer_iserializer { private: virtual const basic_iserializer & get_basic_serializer() const { return boost::serialization::singleton >::get_const_instance(); } BOOST_DLLEXPORT virtual void load_object_ptr(basic_iarchive & ar, void * & x, const unsigned int file_version) const BOOST_USED; public: pointer_iserializer(); }; template pointer_iserializer::pointer_iserializer() : archive_pointer_iserializer(boost::serialization::type_info_implementation::type::get_const_instance()) { boost::serialization::singleton >::get_mutable_instance().set_bpis(this); } template BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr(basic_iarchive &ar, void *&x, const unsigned int file_version) const { Archive &ar_impl = boost::serialization::smart_cast_reference(ar); size_t extra; ar_impl >> extra; // a hook at this point would be nice and similar in the pointer_oserializer // maybe some global function that can be specialised??? auto_ptr_with_deleter ap(new(extra) Derived(extra)); if(NULL == ap.get()) boost::serialization::throw_exception(std::bad_alloc()) ; Derived* t = ap.get(); x = t; BOOST_TRY { ar.next_object_pointer(t); boost::serialization::load_construct_data_adl(ar_impl, t, file_version); } BOOST_CATCH(...) { ap.release(); BOOST_RETHROW; } BOOST_CATCH_END ar_impl >> boost::serialization::make_nvp(NULL, *t); ap.release(); } } } } BOOST_CLASS_EXPORT_GUID(Derived, "Derived") int main() { std::ofstream ofs("filename"); Base *x1 = new(42) Derived(42), *x2 = new(13) Derived(13), *x3 = x1; { boost::archive::text_oarchive oa(ofs); oa << x1; oa << x2; oa << x3; } std::cout << "before" << std::endl; x1->print(); x2->print(); x3->print(); delete x1; delete x2; Base *y1, *y2, *y3; { std::ifstream ifs("filename"); boost::archive::text_iarchive ia(ifs); ia >> y1; ia >> y2; ia >> y3; } std::cout << "after" << std::endl; y1->print(); y2->print(); y3->print(); delete y1; delete y2; return 0; }