[Serialization] good practice for serialization with private default constructors
I am interested to know what is good practice when dealing with serializable classes with private default constructors. In particular it is not clear what is the cleanest way to deserializing these objects. Explaining with reference to the example from: http://stackoverflow.com/questions/7123613/boost-serialization-does-the-defa... The answer to this stackoverflow question shows how to serialize/deserialize an object with a private default constructor. Summarizing: class Colour { friend class boost::serialization::access; // private default constructor // template serialize function public: boost::shared_ptr<Colour> test() { // returns new object; } }; int main(){ boost::shared_ptr<Colour> c = Colour::test(); std::stringstream str; boost::archive::text_oarchive oa(str); oa & c; // ... c.reset(); boost::archive::text_iarchive ia(str); ia & c; } However, it is important to observe that it is not just serializing/deserializing the object itself but also the shared pointer to the object! So for example: replacing "ao & c;" with "oa & *c;" will compile and properly serialize (only) the object, but will throw an exception when it tries to deserialize because it is expecting a shared pointer to the object. My solution to this is to provide a constructor that takes an archive object: class Colour { // other stuff public: template<typename Archive> Colour(Archive& ar) { ar >> *this; } }; // some explicit specializations where there are // other single argument constructors The example main then becomes: int main(){ boost::shared_ptr<Colour> c = Colour::test(); std::stringstream str; boost::archive::text_oarchive oa(str); oa & *c; // ... boost::archive::text_iarchive ia(str); Colour c2(ia); } The above works and is clean in that only the Colour object is being serialized/deserialized. However, I'm not sure if it is good practice. In particular: - I presume there will be an intermediate copy of the Colour object being created by the archive object. - Passing *this to a function that takes an object of type Object from within the constructor seems like a bad thing. - In general template based constructors seems like they should be avoided. So, my question is whether my solution is reasonable or is there a better option. Regards, Dave R.
participants (1)
-
David Rajaratnam