Polymorphism ============ cereal supports serializing pointers to polymorphic base classes, and will automatically deduce the derived types at runtime. --- ### TLDR Version If you want to serialize some data through pointers to base types: 1. Include `` 2. Include all of the archives you want to be able to use with your class (` #include #include // Include the polymorphic serialization and registration mechanisms #include #include #include // An abstract base class struct BaseClass { virtual void sayType() = 0; template void serialize( Archive & ar ) { } }; // A class derived from BaseClass struct DerivedClassOne : public BaseClass { void sayType() { std::cout << "DerivedClassOne" << std::endl; } template void serialize( Archive & ar ) { ar( x ); } int x; }; CEREAL_REGISTER_TYPE(DerivedClassOne); // Another class derived from BaseClass struct EmbarrassingDerivedClass : public BaseClass { void sayType() { std::cout << "EmbarrassingDerivedClass. Wait.. I mean DerivedClassTwo!" << std::endl; } float y; template void serialize( Archive & ar ) { ar( y ); } }; CEREAL_REGISTER_TYPE_WITH_NAME(EmbarrassingDerivedClass, "DerivedClassTwo"); int main() { { std::ofstream os( "polymorphism_test.xml" ); cereal::XMLOutputArchive oarchive( os ); // Create instances of the derived classes, but only keep base class pointers std::shared_ptr ptr1 = std::make_shared(); std::shared_ptr ptr2 = std::make_shared(); oarchive( ptr1, ptr2 ); } { std::ifstream is( "polymorphism_test.xml" ); cereal::XMLInputArchive iarchive( is ); // De-serialize the data as base class pointers, and watch as they are // re-instantiated as derived classes std::shared_ptr ptr1; std::shared_ptr ptr2; iarchive( ptr1, ptr2 ); // Ta-da! This should output: ptr1->sayType(); // "DerivedClassOne" ptr2->sayType(); // "EmbarrassingDerivedClass. Wait.. I mean DerivedClassTwo!" } return 0; } ``` --- ### Registering Archives In order for an archive to be used with polymorphic types, it must be registered with the `CEREAL_REGISTER_ARCHIVE` macro. ```cpp namespace mynamespace { class MyNewOutputArchive : public OutputArchive { /* ... */ }; } CEREAL_REGISTER_ARCHIVE(mynamespace::MyNewOutputArchive); ```