|  | SerializationPrivate Base Classes | 
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// test_private_base.cpp
// (C) Copyright 2009 Eric Moyer - http://www.rrsd.com . 
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <fstream>
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{ 
    using ::remove;
}
#endif
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
class Base {
    friend class boost::serialization::access;
    int m_i;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        ar & BOOST_SERIALIZATION_NVP(m_i);
    }
protected:
    bool equals(const Base &rhs) const {
        return m_i == rhs.m_i;
    }
    Base(int i = 0) :
        m_i(i)
    {}
};
class Derived : private Base {
    friend class boost::serialization::access;
private:
    Base & base_cast(){
        return static_cast<Base &>(*this);
    }
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
    }
public:
    bool operator==(const Derived &rhs) const {
        return Base::equals(static_cast<const Base &>(rhs));
    }
    Derived(int i = 0) :
        Base(i)
    {}
};
int
main( int /* argc */, char* /* argv */[] )
{
    const char * testfile = boost::archive::tmpnam(NULL);
    // serialize Derived and Base
    Derived a(1), a1(2);
    {   
        test_ostream os(testfile);
        test_oarchive oa(os);
        oa << boost::serialization::make_nvp("a", a);
    }
    {
        test_istream is(testfile, TEST_STREAM_FLAGS);
        test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
        ia >> boost::serialization::make_nvp("a", a1);
    }
    std::remove(testfile);
    if(a != a1)
        return 1;
    // serialize Derived and Base
    Derived *ta = &a;
    Derived *ta1 = NULL;
    {   
        test_ostream os(testfile);
        test_oarchive oa(os);
        oa << boost::serialization::make_nvp("ta", ta);
    }
    {
        test_istream is(testfile, TEST_STREAM_FLAGS);
        test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
        ia >> boost::serialization::make_nvp("ta", ta1);
    }
    std::remove(testfile);
    if(*ta != *ta1)
        return 1;
    return 0;
}
BOOST_SERIALIZATION_BASE_OBJECT_NVP
is code which links derived and base class definitions in tables used to serialize
derived classes through pointers to a polymorphic base class.  This code requires
the ability to invoke
static_cast<Base &>(Derived &)
which C++ will only permit from within the derived class if the base class is 
private or protected. The program will fail to compile with an error message 
indicating invalid cast.
In order for this code compiler the following alteration must be made:
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version){
        //ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
        ar & boost::serialization::make_nvp(
            "Base",
            static_cast<Base &>(*this)
        );
    }
If we made one of the functions of Base virtual
in order to use the "export" functionality of the serialization library and permit serialization through
a pointer the the base class, we'll be disappointed. Without the ability to
cast to the base class, we can't use the functionality.
© Copyright Robert Ramey 2015. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)