多态序列化瓦特/升压

多态序列化瓦特/升压

问题描述:

我想(反)序列多态载体,但有不同的尝试不同的问题。事件的整个订单是:

I'm trying to (de)serialize a polymorphic vector, but have different issues with different attempts. The entire order of events are:


  • 在服务器端序列化一个多态矢量

  • 发送序列化的字符串在网络上

  • 反序列化到一个新的多态矢量在客户端

  • 编辑在数据载体(包括添加,编辑和删除)在客户端

  • 序列化编辑的矢量多态性在客户端

  • 发送新的序列化的字符串在网络上

  • 反序列化新的多态矢量在服务器端< ---的这是我的问题在于

  • Serialize a Polymorphic Vector on Server Side
  • Send the serialized string over the network
  • De-serialize to a new Polymorphic Vector on Client Side
  • Edit Data in Vector (includes adding, editing and deleting) on Client Side
  • Serialize the edited Polymorphic Vector on Client Side
  • Send the new serialized string over the network
  • De-serialize the new Polymorphic Vector on Server Side <--- This is where my problem lies

我类中派生(和DerivedB,DerivedC等),从阶级基础和放大器派生。一类LotsOfBases持有虚拟基地的载体。

I have Class Derived (and DerivedB, DerivedC etc) which derives from Class Base & a Class LotsOfBases which holds a Vector of Virtual Base.

虽然,我没有看到这可能会导致问题 - 我相信我的问题是因为在矢量从服务器传来的对象是特定的顺序(AAABBCCCCD),当他们回来,他们是在一个随机顺序可以有不同数量的派生类(ABABCDDDA)的。

Although, I don't see how this could be causing the issue - I believe my issue is because the objects in the Vector coming from the Server are in a particular order (AAABBCCCCD) and when they come back they are in a random order and may have different quantities of derived classes (ABABCDDDA).

下面是我失败的尝试。使用下面的方法2,如果我的吉利的我可以将信息发送来回(如类订单保持不变),但是当类类型更改订单,问题开始出现。

Below are my failed attempts. Using method 2 below, if I am lucky I can send information back and forth (if class order remains the same), but when the class types change order, the problems begin to occur.

code使用及放大器;编译/运行时错误:


  1. 没有,当然增加编译,但我得到的运行时问题作为升压不知道哪个类是...所以我尝试:

  1. Compiles with no additions of course, but I get RunTime issues as Boost doesn't know which class is which... So I tried:

ar.template register_type&LT;衍生GT;(); - 注册类在LotsOfBases.h的序列化功能,得到了以下时,在运行时调用:错误@长:()什么:输入流错误 - 这是我有最大的成功,什么是主要上述

ar.template register_type<Derived>() ; - Registering Class in "LotsOfBases.h"'s Serialize Function and got the following when called at RunTime: Error @ RunTime: what(): Input Stream Error - This is where I've had most success and what is mainly mentioned above.

ar.register_type&LT;静... 但是我得到的编译错误,指出它的功能(看到这个其他地方上的*

ar.register_type<static... But I get compile errors stating its a function (saw this else where on *

BOOST_CLASS_EXPORT(衍生); 在.h头文件,这给年底的 N 的每个不同子警告阶级基础和编译失败。错误:`的多个定义`提振::档案::详细:: extra_detail :: init_guid&LT;衍生GT; :: G'

BOOST_CLASS_EXPORT(Derived) ; At the end of the ".h" file which gives n warnings for each different sub-class of Base and fails to compile. Error: multiple definition of ``boost::archive::detail::extra_detail::init_guid<Derived>::g'

我试图在LotsOfBases被Deserialised主要归档注册类。编译器警告

I tried to register the classes with the archiver in the main where LotsOfBases gets Deserialised. Compiler warnings

BOOST_CLASS_EXPORT_IMPLEMENT(TextQuestion)来自的导出类的序列化 - 同样的错误为6 IIRC

BOOST_CLASS_EXPORT_IMPLEMENT(TextQuestion) from Exporting Class Serialization - Same errors as 6 iirc.

以上无需链接是从我的曳通过计算器〜30页是相似的,但提供了他们的解决方案似乎并没有为我工作,或与升压序列化,但有些不相干做的例子。

The examples above without links are from my trolling through ~30 pages on * which are similar but their solutions offered don't seem to work for me or are to do with Boost Serialization but somewhat irrelevant.

以下是我的code的缩短版(无编辑从其他地方使用):

The following is a shortened version of my code (without edits used from elsewhere):

类'code

LotsOfBases:

#include "s11n.h" //Import All Serialization Headers In Correct Order
namespace boost { namespace serialization { class access ; } }

class LotsOfBases
{
  public:
   std::vector<Base *> getAllBases() ;
  protected:
    std::vector<Base *> allBases() ;

    friend class boost::serialization::access ;

    template <typename Archive>
    void serialize(Archive& ar, const unsigned int /*version*/)
    {
        ar & allBases ;
    }

} ;

基地:

#include "s11n.h" //Import All Serialization Headers In Correct Order
namespace boost { namespace serialization { class access ; } }

class Base
{
  public: 
    Base() ;
    ~Base() ;

    virtual std::string getBaseLocation() ;
  protected:
    std::string baseLocation ;

    friend class boost::serialization::access ;

    template <typename Archive>
    void serialize(Archive& ar, const unsigned int /*version*/)
    {
        ar & baseLocation ;
    }
} ;

派生

#include "s11n.h" //Import All Serialization Headers In Correct Order
namespace boost { namespace serialization { class access ; } }

class Derived
{
  public:
    Derived() ;

    bool getIsAttackableBase() ;
  private:
    bool isAttackableBase ;

    typedef Base _super;
    friend class boost::serialization::access ;

    template <typename Archive>
    void serialize(Archive& ar, const unsigned int /*version*/)
    {
        ar & boost::serialization::base_object<_super>(*this) ;
        ar & isAttackableBase ;
    }

我敢肯定,它不应该是那么困难。所以,我想我的问题是...什么我做错了?我应该在哪里开始阅读/现在研究?

I'm sure it shouldn't be so difficult. So, I guess my question is... What am I doing wrong? Where should I start reading/researching now?

我,你,上搜寻如何序列多态数据相当长的一段时间,你的问题是足够翔实帮助我理解我的错误,并且正确的你。因为你的类未完全实现我提供实现你想要什么code例子。在我的例子

I, as you, had searched for quite some time on how to serialize a polymorphic data, and your question was informative enough to help me understand my error, and correct yours. Since your classes are not fully implemented I provide a code example that achieves what you want. In my example

#pragma once
#include <iostream>
#include <vector>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>

using namespace std;
class Parent; // Forward declares 
class Child;  // so my classes are in your order

家庭是您的 LotsOfBases

class Family {

    friend class boost::serialization::access;

public:
    Family() { ; }
    ~Family() { ; }

    vector<Parent*> m_members;
    //////////////////////////////////////////////////////////////////////
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar.template register_type<Child>();
        ar & m_members;
    }
    //////////////////////////////////////////////////////////////////////

};

是您的基本

class Parent {

    friend class boost::serialization::access;

public:
    Parent() : m_name("") { ; } 
    Parent(string name) : m_name(name) { ; }
    ~Parent() { ; }

    virtual string GetName() { return m_name; }
private:

    string m_name;

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

儿童是您的导出

class Child : public Parent {

    friend class boost::serialization::access;

public:
    Child() : Parent(), m_age(0) { ; }
    Child(string name, int id) : Parent(name), m_age(id) { ; }
    ~Child() { ; }
    int m_age;
private:
    //////////////////////////////////////////////////////////////////////
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<Parent>(*this);
        ar & m_age;
    }
    //////////////////////////////////////////////////////////////////////
};

主要(完整性)

int main() {

    Child *timmy = new Child("Timmy", 4);
    Family JohnsonFamily; 
    JohnsonFamily.m_members.push_back(timmy);

    // serialize object into a std::string
    std::string serial_str;
    boost::iostreams::back_insert_device<std::string> inserter(serial_str);
    boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> s(inserter);
    boost::archive::binary_oarchive oa(s);

    oa & JohnsonFamily;
    s.flush();

    // read object backout of standard string into new Family object
    boost::iostreams::basic_array_source<char> device(serial_str.data(), serial_str.size());
    boost::iostreams::stream<boost::iostreams::basic_array_source<char> > t(device);
    boost::archive::binary_iarchive ia(t);

    Family FosterFamily;
    ia & FosterFamily;

    auto baseptr = FosterFamily.m_members[0];
    auto child = dynamic_cast<Child*>(baseptr);
    if (child != nullptr) {
        cout << "Derived type infered from serialized base pointer." << endl;
        cout << child->GetName() << " is " << child->m_age << endl;
    }

    cin.get();
    return 0;
}

我注意到,你的派生实际上并不继承,这肯定是导致问题。此外,关键的一点是,如果你在一个类中有一个多态的容器,那么你必须在该类注册每个派生类型(而不是在基类)。见上面我族类。

I noticed that your Derived doesn't actually inherit, which is certainly causing issues. Also, the key point is that if you have a polymorphic container in a class, then you must register each derived type in the that class (not in the base class). See my Family class above.

希望这有助于你。