123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!--
- (C) Copyright 2002-4 Robert Ramey - 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)
- -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="stylesheet" type="text/css" href="../../../boost.css">
- <link rel="stylesheet" type="text/css" href="style.css">
- <title>Serialization - Private Base Classes</title>
- </head>
- <body link="#0000ff" vlink="#800080">
- <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
- <tr>
- <td valign="top" width="300">
- <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
- </td>
- <td valign="top">
- <h1 align="center">Serialization</h1>
- <h2 align="center">Private Base Classes</h2>
- </td>
- </tr>
- </table>
- <hr>
- In many cases, serialization of private or protected base classes present no special problems.
- This is true for both simple classes and types as well as pointers to those
- classes and types. That is, the following program compiles and runs exactly as one would expect.
- <pre><code>
- /////////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;
- }
- </code></pre>
- Difficulties start to occur when the base class is made polymorphic by the designation
- of one or more functions as "virtual". If a class is polymorphic, the library
- presumes that one will want the ability to serialize a derived class through
- a pointer to the base class. Included in the macro
- <code>
- BOOST_SERIALIZATION_BASE_OBJECT_NVP
- </code>
- is code which links derived and base class definitions in tables used to serialize
- derived classes through pointers to a polymorphinc base class. This code requires
- the ability to invoke
- <code>
- static_cast<Base &>(Derived &)
- </code>
- 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.
- <p>
- In order for this
- code compiler the following alteration must be made:
- <pre><code>
- 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)
- );
- }
- </code></pre>
- With this change the program will now compile.
- <p>
- If we made one of the functions of <code>Base></code> <code>virtual</code>
- 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.
- <hr>
- <p><i>© Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 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)
- </i></p>
- </body>
- </html>
|