Boost logo

Boost Users :

From: Daryle Walker (darylew_at_[hidden])
Date: 2005-12-04 15:01:08


On 12/4/05 11:22 AM, "David Parks" <davidp_at_[hidden]> wrote:

> First off, I apologize for not replying directly to my last message but
> I'm not even sure it's been posted yet -- as I don't have permission to
> post yet (the 'first message is moderated' deal).
>
> Anyway, I wasn't able to make the example in my last post work with any
> sane process but I did get it to work by doing the following:
>
> 1) splitting the stuff into 3 files -- the main driver, the class
> header, and the class .cpp. I put both classes in the class files.
> 2) Including the */archive/* files in the class cpp immediately followed
> by export.hpp... then the class header.
> 3) Including the same archive headers in the class header followed by
> serialization.hpp (I'm sure this could be done lighter but...)
> 4) Including only the class header in main.
> 5) BOOST_CLASS_EXPORT(derived) in the class cpp.
> 6) This is where it starts to diverge from any information in the
> tutorials and documentation. First, I had to switch from text to xml.
> I'm not positive but, if I couldn't get it to work after 12 straight
> hours, I'd guess the text interface is broken.
> 7) You will get a pretty incorrect error (in the header comments) if you
> don't call the base class in the derived class serialization (ar &
> BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);). This is not ideal because
> in many instances, like mine, you might not care about the bases
> serialization if you have a derived class... the derived class is
> 'smarter'. But this I can deal with.

Actually, step [7] is all you had to do. (But I'm not an expert, or even a
novice, in Boost.Serialization.) You did steps 1-6 for nothing. I think
another respondent, who created the library, just did step [7] in his post
and got your sample code to work.

You say that having to call the base implementation within your class's
serialization is mostly problematic. I would say that not calling it would
be problematic. Granted, you do lose the ability to precisely layout the
base sub-object's state; but what happens if the base class has critical
state data that it does _not_ expose? This important data could be private
base class sub-objects without an accessor, private grand-base classes, or
grand-base class sub-objects without an accessor. Your "smarter" derived
class would have to be "too nosey" for its own good.

> What I needed to do was serialize a vector of objects of some base class
> -- you know, like the useless circles and squares of shapes example in
> every intro C++ book. The documentation could use this as an example --
> it has to be one of the most common uses for a serializer.
>
> Oh, one goofy note that thankfully only took a couple of minutes to
> catch: namespaces aren't all the rage but if you make big use of them
> (like me), beware of BOOST_CLASS_EXPORT... it takes a flash of
> inspiration to realize that it's going to try to put colons in your XML
> tags. Even more tricky is the situation where you are calling, say, the
> base-class with BOOST_SERIALIZATION_BASE_OBJECT_NVP. It stringizes this
> without telling you -- it has to. But if you do this

Are you sure you need BOOST_CLASS_EXPORT? I don't think you did in your
sample code.

What's wrong with colons in XML tags? They're legal XML-name characters;
they can even be the first character in such a name.

> ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A::B)
>
> you will get an error but this (thankfully)
>
> using namespace A;
> ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B);
>
> works. I have no idea how to make this friendly.

Maybe you can refer to your (direct) base classes with a typedef:

    class A: public daryle::B, private loki::C
    {
        typedef daryle::B base_type1;
        typedef loki::C base_type2;

        //...

        template < class Archive >
        void serialize( Archive &a, unsigned version )
        {
            a & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_type1);
            a & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_type2);
            //...
        }

        //...
    };

Whatever name alias you use for a base class should be used for the simple
tag name. I don't know what happens for virtual bases, though.

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT hotmail DOT com

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