Boost logo

Boost Users :

From: Ruediger Berlich (ruediger.berlich_at_[hidden])
Date: 2007-04-04 11:27:46


Hi there,
I am trying to serialize an object through a pointer to its base class.

My application is in the field of distributed processing. I have
a "communicator" type of class, which receives pointers from other objects,
serializes them, sends the generated string over a network for further,
remote processing and then deals with the responses. It is supposed to know
nothing about the objects it serializes, except that they contain a
method "toString()", which is contained in the base class.

However, when I call that method, I only get a serialization of that base
class, not of the derived class.

Here is some code to illustrate the problem. The output of the program is
listed at the end of this posting.

How can I achieve serialization of the derived class (without explicit
casting), if it is stored in a pointer to a base class ?

My assumption is that this has to do with the fact that the "serialization"
method cannot be virtual, as it is a member function template.

Any help is appreciated.

Thanks and have a good day,
Ruediger

/*************************************************************************/
// headers and namespace statements removed ...

class base
    :public vector<int>
{
    friend class boost::serialization::access;
    
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        using boost::serialization::make_nvp;
        ar & make_nvp("vector",
             boost::serialization::base_object<std::vector<int> >(*this));
    }

public:
    base(){ /* nothing */ }
    virtual ~base() { /* nothing */ }

    virtual void appendValue(int val) = 0;

    string toString(void){
        ostringstream ofs;
        boost::archive::xml_oarchive oa(ofs);
        // this should point to derived objects
        oa << make_nvp("myp",*this);
        return ofs.str();
    }

    void printType(void){
        cout << typeid(*this).name() << endl;
    }
};

BOOST_IS_ABSTRACT(base);

/****************************************************************************/

class derived
    :public base
{
    friend class boost::serialization::access;
    
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        using boost::serialization::make_nvp;
        ar & make_nvp("base",
             boost::serialization::base_object<base>(*this));
    }

public:
    derived(){ /* nothing */ }
    virtual ~derived() { /* nothing */ }

    void appendValue(int val){
        this->push_back(val);
    }
};

BOOST_CLASS_EXPORT(derived);

/****************************************************************************/

main()
{
    base *myp = new derived();
    myp->appendValue(1);

    // only serializes class "base"
    cout << myp->toString();

    cout << "===========================" << endl;

    myp->printType();
    // this in printType points to the correct type
    cout << "===========================" << endl;

    // Explicit casting to the derived class yields the correct response
    derived *mypp = (derived *)myp;
    ostringstream ofs;
    boost::archive::xml_oarchive oa(ofs);
    oa << make_nvp("myp",*mypp);
    cout << ofs.str() << endl;
}

/****************************************************************************/

Here is the output of the program:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="3">
<myp class_id="0" tracking_level="0" version="0">
        <vector>
                <count>1</count>
                <item>1</item>
        </vector>
</myp>
===========================
7derived
===========================
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="3">
<myp class_id="0" tracking_level="1" version="0" object_id="_0">
        <base class_id="1" tracking_level="0" version="0">
                <vector>
                        <count>1</count>
                        <item>1</item>
                </vector>
        </base>
</myp>


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