|
Boost Users : |
From: Martin Ecker (martin.ecker_at_[hidden])
Date: 2005-07-10 03:21:58
Hi,
Ivan Rachev wrote:
> Does anyone have an idea how to serialize dynamic arrays of objects?
>
> An example follows at the end.
Please post fully working examples. That will make it easier for people to help
you. Your example requires a file test.txt that you didn't send along in your
e-mail.
> Its weakness shows up when an outside
> pointer points to an element in the array. The problem is that the type
> being serialized is T but not T*.
This should actually work fine. I modified your sample to use a memory buffer
instead of a file and added an assert to make sure the deserialized
second-element pointer points to the correct element. The assert does
not trigger with MSVC 7.1.
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/split_member.hpp>
class A
{ friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {}
};
//IVAN Element always points to the beginning of an array of
// 'Size' elements. The array is NOT null-terminated. If
// size == 0, Elements may hold an undefined value. User
// is responsible for initializing, new-ing and delete-ing.
// Assumption: if there is an outside pointer to an object
// inside this array, after loading the array
// that pointer will hold a different object.
template <typename T>
struct DynamicArray
{
int Size;
T* Element;
friend class boost::serialization::access;
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
ar & Size;
for (int i = 0; i < Size; ++i)
ar & Element[i];
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & Size;
//TODO: assert(Size >=0);
if (Size > 0)
{
Element = new T[Size];
for (int i = 0; i < Size; ++i)
ar & Element[i];
}
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
int main(int argc, char* argv[])
{
DynamicArray<A> ArrayOfAs, ArrayOfAs2;
ArrayOfAs.Element = new A[5];
ArrayOfAs.Size = 5;
A* secondElement = &ArrayOfAs.Element[1];
A* secondElement2;
std::stringstream stream;
{
boost::archive::text_oarchive oa(stream);
oa & ArrayOfAs;
oa & secondElement; // this guy will point to a copy of the
// 2nd element but NOT the 2nd element itself
}
{
boost::archive::text_iarchive ia(stream);
ia & ArrayOfAs2;
ia & secondElement2; // this guy will point to a copy of the
// 2nd element but NOT the 2nd element itself
}
// does not trigger, so the above should work
assert(secondElement2 == &ArrayOfAs2.Element[1]);
delete [] ArrayOfAs.Element;
delete [] ArrayOfAs2.Element;
}
Best Regards,
Martin
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