|
Boost : |
Subject: Re: [boost] [serialization]Can I pass the grandparent class toBOOST_SERIALIZATION_BASE_OBJECT_NVP?
From: Takatoshi Kondo (redboltz_at_[hidden])
Date: 2011-04-04 10:48:03
Hi Robert.
On Mon, Apr 4, 2011 at 2:44 AM, Robert Ramey <ramey_at_[hidden]> wrote:
> Hi Takatoshi. Nice hear from you. Havn't heard from you in a while.
Thanks for reply.
BTW, I'll attend the boost-con 2011, I'm looking forward to seeing you again :)
> ... example and expanation in previous post.
>
>> ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A); // My approach
>> // ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B);
>
>> If I pass it B instead of A, the following exception would be
>> occurred. "unregistered void cast struct C<-struct A"
>
> Hmmm ... Are sure you don't mean to say "If I pass it A instead of B"
Oh.. I exactly want to say "If I pass it A instead of B".
Thanks for your mind-reading :)
> One of he side effects of BOOST_SERIALIZATION_BASE_OBJECT_NVP(A) (orB)
> is to invoke void_cast_register<base class, derived class> ...
My understanding is so.
> I would think that you could skip B in this case. But one would have
> to more carefully investigate how this macro is implemented.
>
> Note that if B is implemented as just another macro
> ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
> so things can be done the normal way, I would hope that
> a release build would collapse the code to be equivalent
> to your method of skipping B.
Does "collapse" mean to be omitted by optimizer? (Good meaning?)
> It's also possible the the macro implementation could be
> refined and/or enhanced to permit the skipping of B if it
> doesn't do so already.
>
> Note that the tests/examples include one case where
> the void cast register is called directly - thereby eliminating
> the call to the macro. This short circuits the whole process
> and would be the most efficient. This is why I believe that
> the macro could be modified to directly pass A instead of B
I checked test_void_cast.cpp.
It's very interesting. I can remove the dependency
on the serialization library from class A, B and C completely.
I can add polymorphic serialization capability later (non intrusively).
Amazing!
#include <boost/serialization/serialization.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/export.hpp>
#include <fstream>
// -------------------------------------------------------------------------
struct A {
explicit A(int vala_):vala(vala_) {}
// pure virtual
// to bypass serialize() requirement
// If it is non pure, serialize() and default constructor are required.
virtual ~A() = 0 {}
int vala;
};
struct B : public A {
B(int vala_, int valb_):A(vala_), valb(valb_) {}
int valb;
};
struct C : public B {
C(int vala_, int valb_, int valc_):B(vala_, valb_), valc(valc_) {}
int valc;
};
// -------------------------------------------------------------------------
namespace boost { namespace serialization {
template<class Archive>
void serialize(Archive& /*ar*/, C&, unsigned int const /*version*/) {}
template<class Archive>
void save_construct_data(Archive& ar, C const* p, unsigned int const
/*version*/) {
ar << boost::serialization::make_nvp("vala", p->vala);
ar << boost::serialization::make_nvp("valb", p->valb);
ar << boost::serialization::make_nvp("valc", p->valc);
}
template<class Archive>
void load_construct_data(Archive& ar, C* p, unsigned int const /*version*/) {
int a, b, c;
ar >> boost::serialization::make_nvp("vala", a);
ar >> boost::serialization::make_nvp("valb", b);
ar >> boost::serialization::make_nvp("valc", c);
::new(p) C(a, b, c);
}
}}
BOOST_CLASS_EXPORT(C)
int main()
{
{
std::ofstream ofs("test.xml");
C c(1, 2, 3);
A* a(&c);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("a", a);
}
{
std::ifstream ifs("test.xml");
boost::archive::xml_iarchive ia(ifs);
A* a;
ia >> boost::serialization::make_nvp("a", a);
C* c = dynamic_cast<C*>(a);
assert(c);
assert(c->vala == 1);
assert(c->valb == 2);
assert(c->valc == 3);
delete a;
}
// void_cast_register direct call
boost::serialization::void_cast_register<C, A>(
static_cast<C *>(NULL),
static_cast<A *>(NULL)
);
}
P.S.
I'm in the business trip now. I can't access my primary email account now.
This is my second email address.
Regards,
Takatoshi
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk