派生对象的提升序列化不调用派生对象的序列化()

boost serialization of derived object doesn't call derived's serialize()

本文关键字:派生 序列化 对象 调用 升序      更新时间:2023-10-16

我已经读了很多类似的问题,但还没有找到答案。我使用的是Visual Studio 2010和boost 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: %srn",os.str().c_str()); 
    return (0);
}

你可以看到它非常简单,我添加了BOOST_CLASS_EXPORT和oa.register_type魔术,它应该确保DerivdObject::serialize()被调用,即使它不是一个虚拟方法。。但仍然只调用BaseObject中的serialize()。可能是Visual C++特有的问题?请给我建议?

如boost序列化文档中所述,您需要告诉派生类调用基类序列化代码。只需像这样编写派生类序列化方法:

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

我还没有在调试器中尝试过,但看起来可能是切片的情况。也许您可以通过修改代码以按指针或引用而不是按值进行序列化来找到答案,比如…

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

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

这不是一个严格意义上的答案,只是一个笨拙的解决方法。

在基类中添加:

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

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

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

然后主要更换

oa << base;

带有

base.StreamToArchive(oa);

是的,我知道,它很难看,但是。。好吧,它起作用了,我只需要把STREAMTOARCHIVE宏放在派生类中。。。我可以接受。。。

但是。。。把它解析回一个对象,现在这是另一回事了。。。

编辑:将"this"更改为"*this"