0

Okay, I recently switched to boost and I partitialy understand serializing simple objects or simple classes (the boost tutorial confuses me), but how can I serialize a 3D array which contains class members?

I have an array (std::vector) called TileList, which contains objects which are of a class Tile and class Tile contains nothing else than two variables, int TileID and int TilePassability.

I tried doing it as the Serialization tutorial does in the non obtrusive method and the STL Container method, but I just get a stack of errors in return. Can somebody explain how to do it properly? Thank you.

Speed
  • 1,424
  • 1
  • 16
  • 24
  • Post the code you tried and the errors you get. – Cat Plus Plus May 21 '11 at 20:17
  • Well I know my code is completely wrong, so I was hoping for a simple example on something similar (serializing a vector with class object members) – Speed May 21 '11 at 20:30
  • having been there myself I can attest: no! You need to fix your code or you won't start to se the logic in it. Boost may be crowded (_at least the errors_) but it is mighty consistent. Allow yourself to see the patterns. (50% says you miss an include; 30% says you mixed namespaces (placeholders?) 2% says you hit a bug or limitation) – sehe May 21 '11 at 21:45
  • @sehe: Yeah, I learned that in the last few months the hard way, but all I needed was a simple example to make me understand how to make it work. – Speed May 21 '11 at 21:54

1 Answers1

2

So I understand you have something like this (that's not really a 3D array, post the exact code you want to serialise if I misread you):

struct Tile {
    int id, passability;
};

std::vector<Tile> tileList;

Because std::vector is already serialisable through standard Boost.Serialization facilities, you only need to make Tile serialisable. The easiest way is to add a serialize member that does both the loading and saving.

struct Tile {
   int id, passability;

   template <typename Archive>
   void serialize(Archive& ar, const unsigned version) {
       ar & id;
       ar & passability;
   }
};

Aand that's about it, your type is now serialisable. Special things to be considered include class members being private — you need to add friend declaration for Boost.Serialization in this case, i.e.

class Tile {
    int id, passability;
    friend class boost::serialization::access;

    template <typename Archive>
    void serialize(Archive& ar, const unsigned version) {
        ar & id;
        ar & passability;
    }
public:
    Tile(int, int);
};

serialize member have to be a template (well, not really; but until you know the library a bit better, it have to be), so its entire body must be included within the class declaration (unless you use explicit instantiation, but that's also not something for beginners).

You can also split it into save and load members, but that's not useful until you start using versioning. It would look like this:

struct Tile {
    int id, passability;

    BOOST_SERIALIZATION_SPLIT_MEMBER()
    template <typename Archive>
    void save(Archive& ar, const unsigned version) { ... }
    template <typename Archive>
    void load(Archive& ar, const unsigned version) { ... }
};

That makes the type held by the vector serialisable. Serialising a vector itself is just archive & tileList.

Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • Thank you for your help, I managed to modify it to fit my code and it works (Only error I got was that Visual Studio requested libboost_serialization-vc100-mt-1_46_1.lib instead of just boost_serialization-vc100-mt-1_46_1). I just have a final question, how can I load back the serialized object into the same array? I saved it using an ofstream. Oh and yes it is a 3D array, I have TileList[x][y][z] where each entry equals to a Tile (It's for a simple game I'm doing to learn SDL) – Speed May 21 '11 at 21:25
  • @Speed: Same way, `&` works for both reading and writing. Just use `iarchive`. – Cat Plus Plus May 21 '11 at 21:27
  • I just have one more question: "Oh and yes it is a 3D array, I have TileList[x][y][z] where each entry equals to a Tile (It's for a simple game I'm doing to learn SDL)". Does that make the serialization any different? – Speed May 21 '11 at 21:29
  • @Speed: Well, you've said vector. If you have multidim arrays, then consider using Boost.MultiArray. I don't remember if it's serialisable by default — if not, you can use three for loops and serialise each `TileList[i][j][k]`. Serialising raw arrays should just work, though. – Cat Plus Plus May 21 '11 at 21:32
  • No no, I have a 3D vector (std::vector>>). And by the looks of it, serialization of these works just fine as everything compiled and worked perfectly. Thank you! – Speed May 21 '11 at 21:53