Boost logo

Boost Users :

From: Darryl Lawson (darryl.lawson_at_[hidden])
Date: 2007-12-11 23:41:02


Peter Dimov wrote:
> You can add
>
> virtual void load( boost::archive::text_iarchive& ar, unsigned v )
> = 0;
> virtual void save( boost::archive::text_oarchive& ar, unsigned v )
> = 0;
>
> to base and call them in A::serialize, but this obviously only works
> for a
> specific archive type.

I specifically need to be able to support different archives, so this
won't work - but I think something similar to what you have suggested will.

Robert Ramey wrote:
> How about the following:
>
> template<class Archive>
> void save(Archive& ar, const unsigned int version) const {
> ar << _m;
> cout << "serialise A, _m = " << (unsigned long)_m << endl;}
>
> void save(Archive& ar, const unsigned int version) const {
> base * t;
> ar >> t; // deserialize to a temporary
> // modify _m according to t
> cout << "serialise A, _m = " << (unsigned long)_m << endl;
> delete t;
>
> }

Yeh something like this would do the trick.

So actually, what I am thinking of is a kind of a mix of Robert's and
Peter's suggestions (see code below). It is not the prettiest, but I
think I should only have to do this for one class hierarchy in
particular, so it isn't too bad.

Thanks for your help. The serialization library is going to make my life
a lot easier!

Darryl Lawson

#include <iostream>
#include <fstream>
#include <cassert>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>

using namespace std;

struct base {
    virtual ~base() {}

    template<class Archive>
    void serialize(Archive& ar, const unsigned int version) {}

    virtual void load(const base* rhs) {}
};

struct derived : public base {
    derived() : base(), _value(0) {}

    template<class Archive>
    void serialize(Archive& ar, const unsigned int version) {
        boost::serialization::void_cast_register<derived, base>();
        ar & _value;
    }

    virtual void load(const base* rhs) {
        const derived* t = dynamic_cast<const derived*>(rhs);
        assert(t);
        if (!t)
            return;

        _value = t->_value;
    }

    int _value;
};

BOOST_CLASS_EXPORT(derived);

struct A {
    A() {
        _m = new derived;
        cout << "construct A, _m = " << (unsigned long)_m << endl;
    }

    template<class Archive>
    void save(Archive & ar, const unsigned int version) const {
        ar << _m;
        cout << "save A, _m = " << (unsigned long)_m << endl;
    }

    template<class Archive>
    void load(Archive & ar, const unsigned int version) {
        base* t;
        ar >> t;
        _m->load(t);
        delete t;
        cout << "load A, _m = " << (unsigned long)_m << endl;
    }

    BOOST_SERIALIZATION_SPLIT_MEMBER();

private:
    base* _m;
};

void save(const A& a, const char* filename) {
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << a;
}
                                                                                                         

void load(A& a, const char* filename) {
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);
    ia >> a;
}

int main(int argc, char* argv[]) {
    A a;
    save(a, "archive.txt");
    A new_a;
    load(new_a, "archive.txt");
    return 0;
}


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