#include <boost/serialization/is_abstract.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>

typedef boost::archive::text_iarchive iarchive_t;
typedef boost::archive::text_oarchive oarchive_t;

struct base
{
  virtual ~base(){}
  virtual std::string get_id() const = 0;
private:
  friend class boost::serialization::access;
  template<typename Archive>
  void serialize(Archive&,unsigned int)
  {    
  }
};

BOOST_IS_ABSTRACT(base);

struct derived : public base
{
  derived(std::string const & id):id_(id){}
  std::string get_id() const
  {
    return id_;
  }
private:
  std::string const id_;

  friend class boost::serialization::access;
  template<typename Archive>
  void serialize(Archive & ar, unsigned int)
  {
    ar & boost::serialization::base_object<base>(*this);
    ar & const_cast<std::string&>(id_);
  }
  derived(){} // for serialization only
};

BOOST_CLASS_EXPORT(base);
BOOST_CLASS_EXPORT(derived);

#include <boost/serialization/shared_ptr.hpp>

BOOST_SERIALIZATION_SHARED_PTR(base);
BOOST_SERIALIZATION_SHARED_PTR(derived);

#include <sstream>
#include <iostream>
#include <boost/serialization/nvp.hpp>

int main()
{
  try
  {
    typedef boost::shared_ptr<base> base_ptr_t;

    std::string the_string;
    {
      base_ptr_t b(new derived("derived id"));
      
      std::stringstream os;
      {
        oarchive_t oa(os);
        oa << boost::serialization::make_nvp("b",b);
      }
      the_string = os.str();
      std::cout << "Serialized form: " << the_string << std::endl;
    }
    {
      base_ptr_t b;
      std::stringstream is(the_string);
      {
        iarchive_t ia(is);
        ia >> boost::serialization::make_nvp("b",b);
      }
      std::cout << b->get_id() << std::endl;
    }
  }
  catch(std::exception const & e)
  {
    std::cout << "Oops: " << e.what() << std::endl;
  }
}
