Boost logo

Boost Users :

From: Martin Proulx (mproulx_at_[hidden])
Date: 2005-09-08 09:43:11


> 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 <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>

using namespace std;

class Person
{
public:
    Person(const string& name) : _name(name), _favoriteFood("none") {}
   
    const string& getName() const {return _name;}
    const string& getFavoriteFood() const {return _favoriteFood;}
    void setFavoriteFood(const string& favoriteFood) {_favoriteFood =
favoriteFood;}

private:
    const string _name;
    string _favoriteFood;

    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & _favoriteFood;
    }
};

namespace boost {
namespace serialization {

template<class Archive>
inline void save_construct_data(Archive & ar, const Person * person,
const unsigned int /* file_version */)
{
    ar << person->getName();
}

template<class Archive>
inline void load_construct_data(Archive & ar, Person * person, const
unsigned int /* file_version */)
{
    string name;
    ar >> name;
    ::new(person)Person(name);
}

} // serialization
} // namespace boost

template<class Archive>
void serializePerson(Archive& oa, const Person& someone)
{
    // save_construct_data isn't called when serializing a Person in
this fashion.
    // The person's name will not appear in the archive.
    oa << someone;
}

template<class Archive>
Person UnserializePerson(Archive& ia)
{
    // I'm constructing a temporary person, with a bogus name, as it's
the only workaround I've come up with.
    // There is no way that unserializing returns an actual object, like
I'm needing here.
    Person someone("bogus name");

    // When unserializing in this fashion, load_construct_data isn't
called either.
    ia >> someone;

    // The initial person's name is then lost.
    return someone;
}

void main(void)
{
    Person *const Joe = new Person("Joe");
    Person John("John");

    stringstream stringStream;

    boost::archive::text_oarchive oa(stringStream);
    oa << Joe;
    serializePerson(oa, John);

    boost::archive::text_iarchive ia(stringStream);
    Person* restoredPersonPointer;
    ia >> restoredPersonPointer;
    Person restoredPerson(UnserializePerson(ia));

    assert(restoredPersonPointer->getName() == Joe->getName()); // works
fine.
    assert(restoredPerson.getName() == John.getName()); // fails.
}

-- 
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.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net