Boost C++ Libraries: Ticket #4026: Request to trap missing serialize method in derived class(es) https://svn.boost.org/trac10/ticket/4026 <p> Is there a way the serialization library can trap (or warn of) accidental serialization of a derived class, where the implementor has not added a serialize method for the derived class? </p> <p> The "Base Classes" section of the documentation says: <br /> "For this reason, all serialize member functions should be private." <br /> However, this does not help (at least for MSVC71) for cases where the serialize method is completely missing in the derived class; the derived class is implicitly converted to the base (is-a). </p> <p> This case can easily be missed, and results in invalid data as soon as versioned data is added to the base class. This is demonstrated in the example code, below. </p> <p> I don't know if it can be achieved, but at the point of serialization, where the library knows the type that is being serialized, it would be useful if it could warn if the serialize method being called was not a member of the *exact* type (clearly only for class types). If the call is falling through to the base then it is probably (always?) an oversight. </p> <p> Perhaps if there was a class sitting between 'Base' and 'Derived' then that may be a case for not wanting the warning, but it seems like good practice to add the serialize method anyway. </p> <p> If a warning message is unsuitable, then it would useful to have a documentation update along the lines of: <br /> If there is any chance of using polymorphism or changing the version of a class then ensure all derived classes implement the serialize method, making the base_object&lt;&gt; call at a minimum. <br /> </p> <hr /> <pre class="wiki">#include &lt;boost/archive/text_oarchive.hpp&gt; #include &lt;boost/serialization/serialization.hpp&gt; #include &lt;boost/serialization/base_object.hpp&gt; #include &lt;sstream&gt; class Base { private: friend class boost::serialization::access; template &lt;typename A&gt; void serialize(A &amp;/*a*/, const unsigned v) { assert(v == 1); // Uh-oh, we're picking up version of 'Derived' } }; BOOST_CLASS_VERSION(Base, 1); class Derived : public Base { // Implementor 'forgets' to add: // template &lt;typename A&gt; // void serialize(A &amp;a, const unsigned v) // { // a &amp; boost::serialization::base_object&lt;Base&gt;(*this); // } }; int main(int, char *[]) { std::ostringstream ostr; boost::archive::text_oarchive oa(ostr); Derived d; // Ideally we should be forced to: // Base &amp;b = d; // oa &amp; b; // if no serialize method is found for 'Derived' oa &amp; d; return 0; } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4026 Trac 1.4.3 Robert Ramey Sat, 20 Mar 2010 06:32:00 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/4026#comment:1 https://svn.boost.org/trac10/ticket/4026#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I like this idea, but I couldn't figure out a way to implement it. If you think of one, let me know. BTW, if you use </p> <pre class="wiki">class Derived : private Base </pre><p> your program will trap. Maybe that fact might be useful. </p> <p> Robert Ramey </p> Ticket