boost::serialization - prevent object creation when loading a pointer

I realise that what I am doing is no doubt an unconventional usage of boost::serialization, but I wonder if any one has done a similar thing before. I wish to serialize a derived class through a baseclass pointer, but on deserilize I do not want the object to be created (I do not want memory allocated) - as the object will have all ready been created. An example, hopefully showing what I mean, is given at the end. The program will output something like, construct A, _m = 155640808 serialise A, _m = 155640808 construct A, _m = 155649400 serialise A, _m = 155649808 But essentially I want the program to output something lke, construct A, _m = 155640808 serialise A, _m = 155640808 construct A, _m = 155649400 serialise A, _m = 155649400 i.e. the second lot of construct A/serialise A will have the same address for _m. The reason why I need this behaviour, is that only a sub-set of the derived class will be seriliazed, with the other parts of the class intialised differently depending on the session, and the initialisation of the class is always done _before_ deserialisation. Is there anyway to get this behaviour from the boost::serialization library? Many thanks, Darryl Example ------- #include <fstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp> using namespace std; struct base { virtual ~base() {} template<class Archive> void serialize(Archive& ar, const unsigned int version) {} }; struct derived : public base { derived() : base(), _value(0) {} template<class Archive> void serialize(Archive& ar, const unsigned int version) { boost::serialization::void_cast_register<derived, base>(); ar & _value; } int _value; }; BOOST_CLASS_EXPORT(derived); struct A { A() { _m = new derived; cout << "construct A, _m = " << (unsigned long)_m << endl; } template<class Archive> void serialize(Archive& ar, const unsigned int version) { // On deserialize this will create a new object, but I do not want it to, // rather I would like it to deserialize into the all ready created // object. ar & _m; cout << "serialise A, _m = " << (unsigned long)_m << endl; } base* _m; }; void save(const A& a, const char* filename) { std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << a; } void load(A& a, const char* filename) { std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> a; } int main(int argc, char* argv[]) { A a; save(a, "archive.txt"); A new_a; load(new_a, "archive.txt"); return 0; }

Darryl Lawson:
I realise that what I am doing is no doubt an unconventional usage of boost::serialization, but I wonder if any one has done a similar thing before.
I wish to serialize a derived class through a baseclass pointer, but on deserilize I do not want the object to be created (I do not want memory allocated) - as the object will have all ready been created.
An example, hopefully showing what I mean, is given at the end.
...
struct A { A() { _m = new derived; cout << "construct A, _m = " << (unsigned long)_m << endl; }
template<class Archive> void serialize(Archive& ar, const unsigned int version) { // On deserialize this will create a new object, but I do not want it to, // rather I would like it to deserialize into the all ready created // object. ar & _m; cout << "serialise A, _m = " << (unsigned long)_m << endl; }
base* _m; };
void save(const A& a, const char* filename) { std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << a; }
void load(A& a, const char* filename) { std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> a; }
You can add virtual void load( boost::archive::text_iarchive& ar, unsigned v ) = 0; virtual void save( boost::archive::text_oarchive& ar, unsigned v ) = 0; to base and call them in A::serialize, but this obviously only works for a specific archive type.

How about the following: template<class Archive> void save(Archive& ar, const unsigned int version) const { ar << _m; cout << "serialise A, _m = " << (unsigned long)_m << endl; } void save(Archive& ar, const unsigned int version) const { base * t; ar >> t; // deserialize to a temporary // modify _m according to t cout << "serialise A, _m = " << (unsigned long)_m << endl; delete t; } Robert Ramey Darryl Lawson wrote:
I realise that what I am doing is no doubt an unconventional usage of boost::serialization, but I wonder if any one has done a similar thing before.
I wish to serialize a derived class through a baseclass pointer, but on deserilize I do not want the object to be created (I do not want memory allocated) - as the object will have all ready been created.
An example, hopefully showing what I mean, is given at the end. The program will output something like,
construct A, _m = 155640808 serialise A, _m = 155640808 construct A, _m = 155649400 serialise A, _m = 155649808
But essentially I want the program to output something lke,
construct A, _m = 155640808 serialise A, _m = 155640808 construct A, _m = 155649400 serialise A, _m = 155649400
i.e. the second lot of construct A/serialise A will have the same address for _m.
The reason why I need this behaviour, is that only a sub-set of the derived class will be seriliazed, with the other parts of the class intialised differently depending on the session, and the initialisation of the class is always done _before_ deserialisation.
Is there anyway to get this behaviour from the boost::serialization library?
Many thanks, Darryl
Example -------
#include <fstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp>
using namespace std;
struct base { virtual ~base() {} template<class Archive> void serialize(Archive& ar, const unsigned int version) {} };
struct derived : public base { derived() : base(), _value(0) {}
template<class Archive> void serialize(Archive& ar, const unsigned int version) { boost::serialization::void_cast_register<derived, base>(); ar & _value; }
int _value; };
BOOST_CLASS_EXPORT(derived);
struct A { A() { _m = new derived; cout << "construct A, _m = " << (unsigned long)_m << endl; }
template<class Archive> void serialize(Archive& ar, const unsigned int version) { // On deserialize this will create a new object, but I do not want it to, // rather I would like it to deserialize into the all ready created // object. ar & _m; cout << "serialise A, _m = " << (unsigned long)_m << endl; }
base* _m; };
void save(const A& a, const char* filename) { std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << a; }
void load(A& a, const char* filename) { std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> a; }
int main(int argc, char* argv[]) { A a; save(a, "archive.txt"); A new_a; load(new_a, "archive.txt"); return 0; }
participants (3)
-
Darryl Lawson
-
Peter Dimov
-
Robert Ramey