boost派生对象的序列化不会调用derived的serialize()

时间:2012-03-15 10:41:53

标签: c++ serialization boost export derived

我已阅读了大量类似问题,但未找到答案。我正在使用Visual Studio 2010并提升1.47。

这是代码,它是完整的和可编译的:

#include "stdafx.h"

#include <string>
#include <sstream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include <boost/serialization/export.hpp>

using namespace std;

class BaseObject 
{
public:

    BaseObject(void) { };
    virtual ~BaseObject(void) { };

    template<class Archive>
      void serialize(Archive &ar, const unsigned int version)
      { /* nothing happens here */  };
};

class DerivedObject : public BaseObject
{
public:

    string text;

public:

    DerivedObject(void) { };
    ~DerivedObject(void) { };

    template<class Archive>
      void serialize(Archive &ar, const unsigned int version)
      {
          ar & text;
      };
};

BOOST_CLASS_EXPORT(DerivedObject)

int _tmain(int argc, _TCHAR* argv[])
{
    DerivedObject der;
    der.text = "Testing!";

    std::ostringstream os;
    boost::archive::text_oarchive oa(os);
    oa.register_type<DerivedObject>();

    // I made a DerivedObject, but I'm casting it to a BaseObject
    // as the serialization code should not have to know what type it is
    BaseObject *base = &der;
    // now serialize it
    oa << *base;

    printf("serialized: %s\r\n",os.str().c_str()); 

    return (0);
}

你可以看到它真的很简单,我已经添加了BOOST_CLASS_EXPORT和oa.register_type魔法,它应该确保调用DerivdObject :: serialize(),即使它不是虚方法..但仍然只是序列化调用BaseObject中的()。也许是Visual C ++特有的问题?请指教?

3 个答案:

答案 0 :(得分:2)

boost serialization documentation中所述,您需要告诉派生类调用基类序列化代码。只需编写你的派生类序列化方法:

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

答案 1 :(得分:0)

我没有在调试器或其他任何东西中试过这个,但看起来它可能是切片的情况。也许你可以通过修改你的代码来通过指针或引用而不是按值来序列化,就像这样......

BaseObject *base = &der;
oa << base;  // Serialize a pointer

...或...

BaseObject& base = der;
oa << base;  // Serialize a reference

答案 2 :(得分:0)

这不是一个严格的答案,只是一个愚蠢的解决方法。

在基类中添加:

virtual void StreamToArchive(boost::archive::text_oarchive &oa) = 0;

然后定义一个宏STREAMTOARCHIVE并将其放到每个派生类中。

#define STREAMTOARCHIVE void StreamToArchive(boost::archive::text_oarchive &oa) { oa << *this; }

然后在main中,替换

oa << base;

base.StreamToArchive(oa);

是的,我知道,它很难看,但是......它很有效,我只需要将STREAMTOARCHIVE宏放在派生类中......我可以忍受......

然后......将它解析回一个物体,现在又是另一回事......

已编辑:将'this'更改为'* this'