Re: [Boost-users] [serialization, 1_33_0] Correct usage and implementation for serializable objects without default constructors

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
Hello,
As this discussion is going, it seems clear that either I'm missing
something somewhere or that I'm not being clear enough in exposing my
problems... I'll directly include a sample of something similar to what
I'd like to achieve that doesn't work. Please take a look at the
example, and let me know how you would modify this to make both assert
succeed. If you notice that I've missed some concept in the way the
library should be used, please enlighten me!
Thanks,
Martin
------------------------------------------------------------------------
#include <cstdlib>
#include <cassert>
#include <sstream>
#include

signatureOK I see the problem now. Let me re-state it to be sure we're on the same page. The class Person has a const member _name. In C++ const members can only be set when an object is constructed. In order to make sure no object is created without a name, There is no default constructor. When the serialization library creates a new instance - that is when loading a pointer, the library uses the non-default constructor to initialize the const variable with the correct value. When restoring the contents of an instance of the class Person that already exists the const member is not set. Which seems totally correct to me. The real question here is what is the intent in setting the member variable _name as const? Standard C++ behavior for const members is that they a) are only set when the instance is constructed. b) cannot be changed thereafter. Now if we do the following: Person p("bob") ... ar << p; ... Person p1("anne"); ... ar >> p1; What should p1 contain? If you want p1 to contain "anne", then leave your program as it is. If you want it to contain "bob" then: a) remove the const from the member _name b) implement the normal member serialization for _name. c) at this point, loading pointers will result in _name being loaded twice. If this is a problem, you could i) add a default constructor and elminate the save/load construct data. You might want to make the default constructor private and include friend boost::serialization::access to your class. (I haven't tried this but I believe it should work. An alternative to a) above would be to leave the "const" but use a const_cast inside the class serialization function. At the heart of the matter here is the what we want const to mean. Should const variables never change during the life of the class? - then we expect p1 to contain "bob". Otherwise they are not really "const" in the traditional C++ sense and should be addressed by removing the const, or a cast or? Robert Ramey


signatureAll the above discussion is really a discussion about what the assignment of an object that has a const member means. Well, in C++, it really doesn't make sense and I agree. That's why I believe there's some tiny piece missing from the serialization library. We should also be able to unserialize instances through a factory that returns an actual object rather than having to use operator>>. Here's some code showing this idea that works along with the previous example. ... I don't think this adds anytihing of value. Robert Ramey

Robert Ramey wrote:
All the above discussion is really a discussion about what the assignment of an object that has a const member means. Well, in C++, it really doesn't make sense and I agree.
That's why I believe there's some tiny piece missing from the serialization library. We should also be able to unserialize instances through a factory that returns an actual object rather than having to use operator>>.
Here's some code showing this idea that works along with the previous example.
...
I don't think this adds anytihing of value.
Robert Ramey
Well, restoring objects using some sort of factory would give us a proper mechanism to restore objects with non default constructors or const members that haven't been serialized through pointers. That would be one way to overcome the assignment like limitation of restoring through operator>>. I believe the idea of a factory also holds well to restore objects serialized through pointers where the objects have to actually be reconstructed. Also, fully restoring all members of an object without a default constructor currently implies writing a different serialize function depending if we are to serialize through pointers only, or directly as well: the members needed to reconstruct are either omitted or not. This makes me believe the support for serializing through pointers is somewhat incongruous to the one for serializing directly. It would be possible to correct this by doing something like always having save_construct_data called, and by using load_construct_data in the factory. Something along those lines is seems to be already done when serializing and unserializing such objects from STL containers. Thank you for your support and the serialization library; It really is a useful piece of software! Martin

signature Well, restoring objects using some sort of factory would give us a proper mechanism to restore objects with non default constructors or const members that haven't been serialized through pointers. That would be one way to overcome the assignment like limitation of restoring through operator>>. I believe the idea of a factory also holds well to restore objects serialized through pointers where the objects have to actually be reconstructed. what I really mean is what is the matter with class A { const X m_x ... template<class Archive> void serialize(Archive & ar, const unsigned int version){ ar >> const_cast<X>(m_x); } }; Doesn't this give the same result in a simpler more transparent way? Robert Ramey

Robert Ramey wrote:
Well, restoring objects using some sort of factory would give us a proper mechanism to restore objects with non default constructors or const members that haven't been serialized through pointers. That would be one way to overcome the assignment like limitation of restoring through operator>>. I believe the idea of a factory also holds well to restore objects serialized through pointers where the objects have to actually be reconstructed.
what I really mean is what is the matter with
class A { const X m_x ... template<class Archive> void serialize(Archive & ar, const unsigned int version){ ar >> const_cast<X>(m_x); } };
Doesn't this give the same result in a simpler more transparent way?
It's true that this is a simple way to do the following: A a(/* With a possible bogus and temporary value for m_x); ia >> a; Now if this is simpler and more transparent than doing something like this: A a(restore_object<A>(ia)); ...I'll leave for C++ language lawyers and you to decide. They just don't mean the same thing, even if the end result might be the same. You can achieve the same results with copy constructors or assignment operators, but they're not the same. As a user, what really isn't simple or transparent is that with the above operator>> solution, for objects without a default constructor, I have to define serialize differently depending if load/save_construct data is called or not. Should I take care of the members needed to reconstruct an instance or not in serialize? I have to know enough about the library to know that serializing an "A*" or a "vector<A>" does call them, but that serializing a "const A&" doesn't. Now what about an array of A??? I believe making an object serializable would just be simpler if the following would be true: -) save_construct_data and load_construct_data are always used. -) We have some function that constructs and returns an object instance using load_construct_data. This removes the possibility of doubly serialized members, the need to const_cast, temporary objects created with bogus parameters, and the ambiguity of what members serialize should take care of. Martin

Hi all, I've just downloaded Boost 1.33 and built it with VC7.0. I specified the Spirit root so that the serialization lib would be compiled as well. I saw the output indicating that the serialization lib was being compiled, and I can also see the .obj files in the bin/boost/libs/serialization/... folders, but I cannot find the corresponding .lib or .dll anywhere?! Did I miss something wrong, or there are some other steps that I need to perform to obtain this .lib? Thanks Alex ___________________________________________________________ How much free photo storage do you get? Store your holiday snaps for FREE with Yahoo! Photos http://uk.photos.yahoo.com

How did you build these? What command did you use? This is usually addressed in the "getting started" section of the manual. Robert Ramey Alexis Gatt wrote:
Hi all,
I've just downloaded Boost 1.33 and built it with VC7.0. I specified the Spirit root so that the serialization lib would be compiled as well. I saw the output indicating that the serialization lib was being compiled, and I can also see the .obj files in the bin/boost/libs/serialization/... folders, but I cannot find the corresponding .lib or .dll anywhere?! Did I miss something wrong, or there are some other steps that I need to perform to obtain this .lib?
Thanks
Alex
___________________________________________________________ How much free photo storage do you get? Store your holiday snaps for FREE with Yahoo! Photos http://uk.photos.yahoo.com

--- Robdert Ramey
How did you build these? What command did you use? This is usually addressed in the "getting started" section of the manual.
Thanks for the answer. I actually followed the instructions provided in the "Getting started" section. I first specified the root of the spirit library by "set SPIRIT_ROOT=E:/Boost/spirit16". I then started the compilation of Boost with the following command "bjam "-sTOOLS=vc7" install". THe compilation of other libraries were successful, as the C:/Boost directory contains many .dll and .lib. But I cant find the serialization lib. Any ideas? Alex ___________________________________________________________ To help you stay safe and secure online, we've developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com

Hi Robert,
signatureAll the above discussion is really a discussion about what the assignment of an object that has a const member means. Well, in C++, it really doesn't make sense and I agree.
That's why I believe there's some tiny piece missing from the serialization library. We should also be able to unserialize instances through a factory that returns an actual object rather than having to use operator>>.
Here's some code showing this idea that works along with the previous example.
...
I don't think this adds anytihing of value.
Is it possible for you to use proper quoting on your replies. It took me quite a while to figure out that: Here's some code showing this idea that works along with the previous example. followed by I don't think this adds anytihing of value. are actually words of two different persons! Besides, what that "signature" word right at the beginning? Thanks, Volodya
participants (4)
-
Alexis Gatt
-
Martin Proulx
-
Robert Ramey
-
Vladimir Prus