无法使用boost :: serialization和shared_ptr反序列化

时间:2014-05-27 13:46:33

标签: c++ polymorphism shared-ptr boost-serialization

我在下面实现了类结构。我想序列化这些对象。

class Base
{
public:
  Base(void) = default;

  virtual double func(void) const = 0;


private:
  friend class boost::serialization::access;
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {}
}; 

class DerivedA : public Base
{
public:
  DerivedA(void) = default;
  DerivedA(double a)
  : a_(a) {}

  virtual double func(void) const
  {
    return std::exp(a_);
  }

private:
  double a_; 

  friend class boost::serialization::access;
  template<class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
    ar & a_;
  }
}; 


class DerivedB : public Base
{
public:
  DerivedB(void) = default;
  DerivedB(double b)
  : b_(b) {}

  virtual double func(void) const
  {
    return std::log(b_);
  }

 private:
   double b_; 

   friend class boost::serialization::access;
   template<class Archive>
   void serialize(Archive & ar, const unsigned int version)
   {
     ar & b_;
   }
 }; 

我想为这些对象创建一个shared_ptr的向量,并对它们进行序列化和反序列化。序列化似乎没问题,但我无法对它们进行反序列化。有什么想法吗?

void out(void)
{
  std::vector<std::shared_ptr<Base>> objects;
  std::shared_ptr<Base> m1(new DerivedA(1.0));
  std::shared_ptr<Base> m2(new DerivedB(4.0));
  objects.push_back(m1);
  objects.push_back(m2);

  std::ofstream ofs("filename");
  boost::archive::text_oarchive oa(ofs);

  for(auto o : objects)
  {
    oa << *o;
  }
}

void in(void)
{
  std::ifstream ifs(filename);
  boost::archive::text_iarchive ia(ifs);

  std::vector<std::shared_ptr<Base>> objects;

  std::shared_ptr<Base> m1(new DerivedA());
  ia >> *m1;
  models.push_back(m1);
  std::shared_ptr<Base> m2(new DerivedB());
  ia >> *m2;
  models.push_back(m2);  
}

干杯,迈克

1 个答案:

答案 0 :(得分:1)

以下是我对此的看法: Live On Coliru

注意:

  • 使用boost::shared_ptr

  • 使用

    BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base)
    BOOST_CLASS_EXPORT_KEY(DerivedA)
    BOOST_CLASS_EXPORT_KEY(DerivedB)
    
  • 使用

    ar & boost::serialization::base_object<Base>(*this);
    

    建立多态链接

  • 使用

    ar.template register_type<DerivedA>();
    ar.template register_type<DerivedB>();
    
  • 通过指针进行序列化,而不是(l)值

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/export.hpp>
#include <boost/make_shared.hpp>
#include <fstream>

class DerivedA;
class DerivedB;

class Base
{
    public:
        Base(void) = default;
        virtual ~Base() = default;

        virtual double func(void) const = 0;

    private:
        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive & ar, const unsigned int version)
            {
                ar.template register_type<DerivedA>();
                ar.template register_type<DerivedB>();
            }
}; 

typedef boost::shared_ptr<Base> BasePtr;

class DerivedA : public Base
{
    public:
        DerivedA(void) = default;
        DerivedA(double a)
            : a_(a) {}

        virtual double func(void) const
        {
            return std::exp(a_);
        }

    private:
        double a_; 

        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive & ar, const unsigned int version)
            {
                ar & boost::serialization::base_object<Base>(*this);
                ar & a_;
            }
}; 


class DerivedB : public Base
{
    public:
        DerivedB(void) = default;
        DerivedB(double b)
            : b_(b) {}

        virtual double func(void) const
        {
            return std::log(b_);
        }

    private:
        double b_; 

        friend class boost::serialization::access;
        template<class Archive>
            void serialize(Archive & ar, const unsigned int version)
            {
                ar & boost::serialization::base_object<Base>(*this);
                ar & b_;
            }
}; 

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base)
BOOST_CLASS_EXPORT_KEY(DerivedA)
BOOST_CLASS_EXPORT_KEY(DerivedB)

void out(std::string filename)
{
    std::vector<BasePtr> objects;
    BasePtr m1(new DerivedA(1.0));
    BasePtr m2(new DerivedB(4.0));
    objects.push_back(m1);
    objects.push_back(m2);

    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa.template register_type<DerivedA>();
    oa.template register_type<DerivedB>();

    oa << objects;
}

std::vector<BasePtr > in(std::string filename)
{
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);
    ia.template register_type<DerivedA>();
    ia.template register_type<DerivedB>();

    std::vector<BasePtr> objects;

    ia >> objects;

    return objects;
}

int main()
{
    out("test.out");
    auto r = in("test.out");
    return r.size();
}