private_base.html 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!--
  4. (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
  5. Use, modification and distribution is subject to the Boost Software
  6. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. -->
  9. <head>
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  11. <link rel="stylesheet" type="text/css" href="../../../boost.css">
  12. <link rel="stylesheet" type="text/css" href="style.css">
  13. <title>Serialization - Private Base Classes</title>
  14. </head>
  15. <body link="#0000ff" vlink="#800080">
  16. <table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
  17. <tr>
  18. <td valign="top" width="300">
  19. <h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../boost.png" border="0"></a></h3>
  20. </td>
  21. <td valign="top">
  22. <h1 align="center">Serialization</h1>
  23. <h2 align="center">Private Base Classes</h2>
  24. </td>
  25. </tr>
  26. </table>
  27. <hr>
  28. In many cases, serialization of private or protected base classes present no special problems.
  29. This is true for both simple classes and types as well as pointers to those
  30. classes and types. That is, the following program compiles and runs exactly as one would expect.
  31. <pre><code>
  32. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  33. // test_private_base.cpp
  34. // (C) Copyright 2009 Eric Moyer - http://www.rrsd.com .
  35. // Use, modification and distribution is subject to the Boost Software
  36. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  37. // http://www.boost.org/LICENSE_1_0.txt)
  38. #include <fstream>
  39. #include <boost/config.hpp>
  40. #if defined(BOOST_NO_STDC_NAMESPACE)
  41. namespace std{
  42. using ::remove;
  43. }
  44. #endif
  45. #include <boost/serialization/access.hpp>
  46. #include <boost/serialization/base_object.hpp>
  47. #include <boost/serialization/export.hpp>
  48. class Base {
  49. friend class boost::serialization::access;
  50. int m_i;
  51. template<class Archive>
  52. void serialize(Archive & ar, const unsigned int version){
  53. ar & BOOST_SERIALIZATION_NVP(m_i);
  54. }
  55. protected:
  56. bool equals(const Base &rhs) const {
  57. return m_i == rhs.m_i;
  58. }
  59. Base(int i = 0) :
  60. m_i(i)
  61. {}
  62. };
  63. class Derived : private Base {
  64. friend class boost::serialization::access;
  65. private:
  66. Base & base_cast(){
  67. return static_cast<Base &>(*this);
  68. }
  69. template<class Archive>
  70. void serialize(Archive & ar, const unsigned int version){
  71. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
  72. }
  73. public:
  74. bool operator==(const Derived &rhs) const {
  75. return Base::equals(static_cast<const Base &>(rhs));
  76. }
  77. Derived(int i = 0) :
  78. Base(i)
  79. {}
  80. };
  81. int
  82. main( int /* argc */, char* /* argv */[] )
  83. {
  84. const char * testfile = boost::archive::tmpnam(NULL);
  85. // serialize Derived and Base
  86. Derived a(1), a1(2);
  87. {
  88. test_ostream os(testfile);
  89. test_oarchive oa(os);
  90. oa << boost::serialization::make_nvp("a", a);
  91. }
  92. {
  93. test_istream is(testfile, TEST_STREAM_FLAGS);
  94. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  95. ia >> boost::serialization::make_nvp("a", a1);
  96. }
  97. std::remove(testfile);
  98. if(a != a1)
  99. return 1;
  100. // serialize Derived and Base
  101. Derived *ta = &a;
  102. Derived *ta1 = NULL;
  103. {
  104. test_ostream os(testfile);
  105. test_oarchive oa(os);
  106. oa << boost::serialization::make_nvp("ta", ta);
  107. }
  108. {
  109. test_istream is(testfile, TEST_STREAM_FLAGS);
  110. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  111. ia >> boost::serialization::make_nvp("ta", ta1);
  112. }
  113. std::remove(testfile);
  114. if(*ta != *ta1)
  115. return 1;
  116. return 0;
  117. }
  118. </code></pre>
  119. Difficulties start to occur when the base class is made polymorphic by the designation
  120. of one or more functions as "virtual". If a class is polymorphic, the library
  121. presumes that one will want the ability to serialize a derived class through
  122. a pointer to the base class. Included in the macro
  123. <code>
  124. BOOST_SERIALIZATION_BASE_OBJECT_NVP
  125. </code>
  126. is code which links derived and base class definitions in tables used to serialize
  127. derived classes through pointers to a polymorphinc base class. This code requires
  128. the ability to invoke
  129. <code>
  130. static_cast&lt;Base &&gt;(Derived &)
  131. </code>
  132. which C++ will only permit from within the derived class if the base class is
  133. private or protected. The program will fail to compile with an error message
  134. indicating invalid cast.
  135. <p>
  136. In order for this
  137. code compiler the following alteration must be made:
  138. <pre><code>
  139. template<class Archive>
  140. void serialize(Archive & ar, const unsigned int version){
  141. //ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
  142. ar & boost::serialization::make_nvp(
  143. "Base",
  144. static_cast&lt;Base &&gt;(*this)
  145. );
  146. }
  147. </code></pre>
  148. With this change the program will now compile.
  149. <p>
  150. If we made one of the functions of <code>Base></code> <code>virtual</code>
  151. in order to use the "export" functionality of the serialization library and permit serialization through
  152. a pointer the the base class, we'll be disappointed. Without the ability to
  153. cast to the base class, we can't use the functionality.
  154. <hr>
  155. <p><i>&copy; Copyright <a href="http://www.rrsd.com">Robert Ramey</a> 2015.
  156. Distributed under the Boost Software License, Version 1.0. (See
  157. accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  158. </i></p>
  159. </body>
  160. </html>