Re: [Boost-users] [serialization] Purpose of load_construct_data (was: Re: Library Interface Design)
Hello Robert,
----- Mensaje original -----
De: Robert Ramey
I am not sure. I'm a little puzzled about the intended purpose of load_construct_data, as the docs and the code of Boost.Serialization seem to suggest that it is used for two incompatible tasks:
a) to construct a dummy object prior to deserialization itself, thus providing a user-overridable hook in case default construction is not appropriate. b) to deserialize in place as explained on the bit you quote.
The intended purpose was to address de-serialization of objects that have no default constructor. See test_non_default_ctor.
My hunch is that Robert started this with b) in mind but finally the facility was kept playing a more humble role as a). Consider for instance, serialization of pointers: currently, if an object instance> is saved exclusively through pointers, Boost.Serialization does the following when the first such pointer is met
save_construct_data(ar,p); // S(0) ar<<*p; // S(1)
and correspondingly at loading time
p=get unitialized storage; load_construct_data(ar,p); // L(0) ar>>*p; // L(1)
By default save_construct_data does nothing and load_construct_data creates a default cted object, effectively leading to a two-phase construction scenario. Now, if the user decides to override (save|load)_construct_data for some class, say foo, so as to perform one-phase construction, we've got the following:
S(0) saves foo contents S(1) saves foo contents again
Nope. save_construct_data saves ONLY that data needed for constructionwhile ar << *p save that data NOT used in construction.
L(0) loads foo contents and creates a foo object with these. L(1) loads foo contents again
Nope - see above.
I believe this is well illustrated by the test_non_default_ctor.cpp example previously cited.
Note that in generally, the data required to construct an instance might not be part of the instance itself. This is also addressed by this api.
I'm not sure, but I suspect this could be also useful in de- serializationof objects which contain references to other objects as references can only be set at object construction time. Tracking would still work.
Thanks for pointing me to test_non_default_ctor.cpp. I think this example nicely illustrates the purposes which (load|save)_construct_data is meant to serve, and that you've summarized in your comments above: * handle types without a default ctor. * serialize data used at construction time which are *not* serialized by T::serialize. and this is all good, but if I'm understanding you right then you're stating (in agreement with my analysis) that (load|save)_construct_data can't be used for one-phase serialization, and that two phases (construction and serialization) are still needed. The original post by Dave said otherwise, though, and I think the misunderstanding comes from the example at http://boost.org/libs/serialization/doc/serialization.html#constructors where my_class serializes my_class::m *both* at my_class::serialize *and* my_class::(load|save)_construct_data. If the analysis I develop in my previous post is correct (is it?) this leads to my_class::m being serialized *twice* when a pointer to my_class is saved. Maybe it would sufice to rewrite this part of the documentation with a more sensible example like the one at test_non_default_ctor.cpp. What do you think?
Robert Ramey
Thank you, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
JOAQUIN LOPEZ MU?Z wrote:
Thanks for pointing me to test_non_default_ctor.cpp. I think this example nicely illustrates the purposes which (load|save)_construct_data is meant to serve, and that you've summarized in your comments above:
* handle types without a default ctor. * serialize data used at construction time which are *not* serialized by T::serialize.
and this is all good, but if I'm understanding you right then you're stating (in agreement with my analysis) that (load|save)_construct_data can't be used for one-phase serialization, and that two phases (construction and serialization) are still needed. The original post by Dave said otherwise, though, and I think the misunderstanding comes from the example at
http://boost.org/libs/serialization/doc/serialization.html#constructors
where my_class serializes my_class::m *both* at my_class::serialize *and* my_class::(load|save)_construct_data. If the analysis I develop in my previous post is correct (is it?) this leads to my_class::m being serialized *twice* when a pointer to my_class is saved. Maybe it would sufice to rewrite this part of the documentation with a more sensible example like the one at test_non_default_ctor.cpp. What do you think?
I agree. The fact that the example uses a member variable confuses the issue. I'll amend the documentation accordingly. However, the current example does illustrate a case where it seems impossible to avoid serializing a member twice. One could leave it in the load_construct_data, and eliminate it from the serialization code - but then this would work only if the object was serialized via a pointer. If it were my program I would say hmmmm - I'm really confusing the role of the variable m - If its to be initialzed at construction - it shouldn't be messed with by serialization or operator= etc. If its realy part of the objects dynamic state - then it shouldn't be required at construction time. Anyway, I'll alter my example to make the variable in question "const" and remove it from serialization which is a better of example of the real cases where this can come up. Robert Ramey
Robert Ramey a écrit :
Anyway, I'll alter my example to make the variable in question "const" and remove it from serialization which is a better of example of the real cases where this can come up.
Having a const variable explains the matter quite clearly, but having an example that illustrates [de]serialisation in two phases would be quite intructive too, IMO. -- Loïc
participants (3)
-
JOAQUIN LOPEZ MU?Z
-
Loïc Joly
-
Robert Ramey