171 lines
5.4 KiB
HTML
171 lines
5.4 KiB
HTML
<!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>
|