повышение сериализации производного объекта не вызывает производную serialize () - PullRequest
6 голосов
/ 15 марта 2012

Я прочитал множество похожих вопросов, но не нашел ответа.Я использую 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 () вызывается, даже если это не виртуальный метод ... но вызывается только serialize () в BaseObject.Проблема, специфичная для Visual C ++, возможно?Пожалуйста, совет?

Ответы [ 3 ]

2 голосов
/ 28 марта 2013

Как описано в документации для расширенной сериализации , вам нужно указать производному классу, чтобы он вызывал код сериализации базового класса. Просто напишите свой сериализованный метод производного класса следующим образом:

  template<class Archive>
  void serialize(Archive &ar, const unsigned int version)
  {
      ar & boost::serialization::base_object<BaseObject>(*this);
      ar & text;
  };
0 голосов
/ 17 марта 2012

Это не совсем ответ, а просто хитрый обходной путь.

В базовый класс добавьте:

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 в производные классы ... Я могу жить с этим ...

Но потом ... чтобы разобрать его обратно в объект, теперь это другое дело ...

Отредактировано: изменено «это» на «* это»

0 голосов
/ 16 марта 2012

Я не пробовал это в отладчике или чем-то еще, но похоже, что это может быть случай нарезки. Возможно, вы могли бы это выяснить, изменив код для сериализации по указателю или по ссылке, а не по значению, например ...

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

... или ...

BaseObject& base = der;
oa << base;  // Serialize a reference
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...