Re: [Boost-users] [serialization, 1_33_0] Correct usage and implementation for serializable objects without default constructors
Hello,
While using the latest release of boost, I've encountered a few questions concerning the usage of the serialization library with objects without default constructors.
Here they are:
1-) How can we construct an instance of a serialized object that doesn't have a default constructor?
The only option I've figured out is to normally construct an object with bogus values, then unserialize the real values while reading from the archive. Example:
X(0) val; // 0 being some bogus value. inputStream >> val; // Overwrites all values within val;
Is this the correct way to do things?
No.. But I think what you want can be found in the manual in section: If you specialize save/load construct data you will get what you want. Use construct in place inside of load construct data. Reference/Serializable/Concept/Pointers/Non-Default Constructors.
2-) How should we split the serialization between the class' serialize member versus load/save_construct_data?
My observations show that when un/serializing objects directly like shown above, load/save_construct_data aren't needed, so the serialize member has to handle everything. When serializing a vector<X>, load/save_construct_data does get called, so we have to un/serialize some members in those functions as well. At first glance, it seems some members will have to be un/serialized for the second time within load/save_construct_data.
Is that correct? For a class to be correctly un/serializable for all cases, load/save_construct_data must un/serialize members that are already taken care of in the serialize member?
Nope.
If his isn't simple, then there is something wrong. Check the code in test_non_default_ctor . If it still doesn't give you what you need, ask again.
RObert Ramey
Hello, Let me rediscuss everything with the example of test_non_default_ctor.cpp at hand. In this example, we have a class A that doesn't have a default constructor. An int is needed by the constructor, which is stored in the i member variable. load/save_construct_data are used to un/serialize the i member, while the serialize member is used for all other members. Looking at this test, I see a couple of behaviors that puzzle me. -) Saving the 'a' instance in the save() function doesn't end up calling save_construct_data. This leaves a serialized version of A which lacks the 'i' member. This makes it impossible to fully restore the 'a' instance. It seems problematic to me that save_construct_data isn't called in this case. In my planned usage, I'd like to fully serialize all members, regardless if the objects are serialized directly or through pointers. I cannot see how to do this without serializing the members needed to reconstruct the object in both serialize and save_construct_data, even if some members will end up serialized twice when an object is stored through a pointer. What's the proper way to serialize all members of a class without a default constructor so that it gets fully serialized regardless how the objects are managed? -) When restoring the 'a' instance within load(), in order to restore it, we first create another 'a' instance (with a different constructor argument), then restore the other members within, leaving untouched the 'i' member. Assuming I'd like to be able to serialize and unserialize completely objects that do not have a default constructor, I'm wondering how I can fully restore an object that doesn't have a default constructor. I currently can only see a single way, and it is the way it's done in load() for the 'a' instance; that is to construct an object with possibly irrelevant constructor arguments, and then unserialize the object from the archive. This has the downside of fully constructing an object with temporary values that will get replaced when we unserialize the real values. I've looked for some other mechanism relying on a copy constructor and something along the lines of load_construct_data, but I haven't found any. Here again, what is the syntax of choice to fully restore an object that doesn't have a default constructor? Thanks! Martin -- Tel: (450) 681-1681, #271 ------------------------------------------------------------------------ OKIOK Enterprise and e-business security solutions Solutions de sécurité d'entreprise et d'affaires électronique Tel. : (450) 681.1681 http://www.okiok.com This e-mail message (including attachments, if any) is intended for the use of the individual or entity to which it is addressed and may contain information that is privileged, proprietary, confidential and exempt from disclosure. If you are not the intended recipient, you are notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender and erase this e-mail message immediately. Le présent message électronique (y compris les pièces qui y sont annexées, le cas échéant) s'adresse au destinataire indiqué et peut contenir des renseignements de caractère privé ou confidentiel. Si vous n'êtes pas le destinataire de ce document, nous vous signalons qu'il est strictement interdit de le diffuser, de le distribuer ou de le reproduire. Si ce message vous a été transmis par erreur, veuillez en informer l'expéditeur et le supprimer immédiatement.
signature In this example, we have a class A that doesn't have a default constructor. An int is needed by the constructor, which is stored in the i member variable. load/save_construct_data are used to un/serialize the i member, while the serialize member is used for all other members. Looking at this test, I see a couple of behaviors that puzzle me. -) Saving the 'a' instance in the save() function doesn't end up calling save_construct_data. This leaves a serialized version of A which lacks the 'i' member. This makes it impossible to fully restore the 'a' instance. It seems problematic to me that save_construct_data isn't called in this case. I just re-ran test_non_default_ctor. I ran under the VC 7.1 debugger and inserted traps inside both save_construct_data and load_construct_data. II verified that save_construct_data and load_construct_data are being invoked exactly as they are intended. I see no problem here. In my planned usage, I'd like to fully serialize all members, regardless if the objects are serialized directly or through pointers. I cannot see how to do this without serializing the members needed to reconstruct the object in both serialize and save_construct_data, even if some members will end up serialized twice when an object is stored through a pointer. If the members are not pointers, the constructor is never called. so the parameters set by the constructor are not needed. save_load_contruct_data is only called when its necessary to create a new object. What's the proper way to serialize all members of a class without a default constructor so that it gets fully serialized regardless how the objects are managed? Exactly as described in the manual and illustrated by the example test_non_default_ctor. -) When restoring the 'a' instance within load(), in order to restore it, we first create another 'a' instance (with a different constructor argument), then restore the other members within, leaving untouched the 'i' member. Assuming I'd like to be able to serialize and unserialize completely objects that do not have a default constructor, I'm wondering how I can fully restore an object that doesn't have a default constructor. All you have to do is define save_construct_data and load_construct_data for all types which don't have a default constructor. The library takes care of everything else. I've looked for some other mechanism relying on a copy constructor and something along the lines of load_construct_data, but I haven't found any. Somehow I'm thinking you're looking for the wrong thing. I wonder if you're not underestimating what the library does for you. As I said, you, only need to define save/load_construct_data for those types which don't have a default constructor - there is nothing else required to do. Robert Ramey
participants (2)
-
Martin Proulx
-
Robert Ramey