I'm having trouble serializing a few classes with boost serialization. I've looked through different documentation and I've found it pretty confusing. Some say that you have to include certain libraries in a certain order, others say you have to use BOOST_SERIALIZATION_BASE_OBJECT_NVP, others boost::serialization::base_object, etc. I've also seen some use BOOST_CLASS_EXPORT() but I don't want to have to list every single possible derived class...

The code:

main.cpp:

#include <iostream>
#include <memory>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
#include "model.h"
#include "c1.h"

int main()
{
        std::shared_ptr<C1> c1 = std::make_shared<C1>();
        Model m(c1);
        std::cout << "TYPE: " << m.which_type_in_use() << std::endl;

        std::ofstream out_stream("test.bin", std::ios::out | std::ios::binary | std::ios::trunc);
        boost::archive::binary_oarchive oar(out_stream);
        oar << (m);

        Model m2;
        std::ifstream    in_stream("test.bin", std::ios::in | std::ios::binary);
        boost::archive::binary_iarchive iar(in_stream);
        iar >> (m2);
        std::cout << "TYPE: " << m2.which_type_in_use() << std::endl;
}

p1.h:

#ifndef P1_H_
#define P1_H_

#include <string>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

class P1
{
protected:
        int size = 100;
        std::string type;
public: 
        int get_size()
        {
                return size;
        }
        virtual std::string get_type() = 0;
        friend class boost::serialization::access;
        template<typename Archive>
        void serialize(Archive &ar, const unsigned int version) {
                ar & size;
                ar & type;
        }
};

#endif

c1.h:

#ifndef C1_H_
#define C1_H_

#include "p1.h"
#include <string>
#include <boost/serialization/serialization.hpp>

class C1 : public P1
{
public: 
        bool is_child = true;
        C1()
        {
                int r = 10;
        }
        std::string get_type();
        template<typename Archive>
        void serialize(Archive &ar, const unsigned int version) {
                ar & is_child;
                ar & boost::serialization::base_object<P1>(*this);
        }
};

#endif

c1.cpp:

#include "c1.h"

std::string C1 :: get_type()
{
        return "c1";
}

model.h:

#ifndef MODEL_H_
#define MODEL_H_

#include <memory>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include "p1.h"

class Model
{
public: 
        bool is_model = true;
        //int *nums;
        std::shared_ptr<P1> p;
        Model(std::shared_ptr<P1> p1);
        Model() = default;
        std::string which_type_in_use();
        template<typename Archive> void serialize(Archive &ar, const unsigned int version);
};

#endif

model.cpp:

#include "model.h"

Model :: Model(std::shared_ptr<P1>  p1) : p(p1)
{
        //nums = (int*)malloc(10*sizeof(int));
        //nums[5] = 123;
}

std::string Model :: which_type_in_use()
{
        return p->get_type();
}

template<typename Archive>
void Model :: serialize(Archive &ar, const unsigned int version) {
                ar & is_model;
                ar & p;
        }