我正在尝试(反)序列化一个多态 vector ,但不同的尝试有不同的问题。整个事件顺序是:
- 在服务器端序列化多态 vector
- 通过网络发送序列化的字符串
- 在客户端反序列化为新的多态 vector
- 在客户端编辑 Vector 中的数据(包括添加、编辑和删除)
- 在客户端序列化编辑后的多态 vector
- 通过网络发送新的序列化字符串
- 在服务器端反序列化新的多态 vector <--- 这就是我的问题所在
我有类 Derived(以及 DerivedB、DerivedC 等),它派生自类 Base 和一个类 LotsOfBases,它包含一个虚拟基 vector 。
不过,我不明白这是怎么引起问题的 - 我相信我的问题是因为来自服务器的 Vector 中的对象是按特定顺序 (AAABBCCCCD) 并且当它们返回时它们处于随机顺序并且可能有不同数量的派生类(ABABCDDDA)。
以下是我失败的尝试。使用下面的方法 2,如果我幸运我可以来回发送信息(如果类顺序保持不变),但是当类类型改变顺序时,问题开始出现。
使用的代码和编译/运行时错误:
编译当然没有添加,但我遇到了运行时问题,因为 Boost 不知道哪个类是哪个...所以我尝试了:
ar.template register_type<Derived>() ;
- Registering Class在“LotsOfBases.h”的序列化函数中,在运行时调用时得到以下信息:Error @ RunTime: what(): Input Stream Error
- 这是我最成功的地方,也是上面主要提到的地方。ar.register_type<static...
但是我得到了编译错误,说明它是一个函数(在 StackOverflow 上的其他地方看到了这个BOOST_CLASS_EXPORT(Derived) ;
在“.h”文件的末尾,它为每个不同的 Base 子类发出 n 警告并且编译失败。错误:multiple definition of ``boost::archive::detail::extra_detail::init_guid<Derived>::g'
我尝试在 LotsOfBases 被反序列化的主目录中向存档器注册类。编译器警告
BOOST_CLASS_EXPORT_IMPLEMENT(TextQuestion)
来自 Exporting Class Serialization - 与 6 iirc 相同的错误。上面没有链接的示例来 self 在 StackOverflow 上浏览了大约 30 页,这些页面很相似,但他们提供的解决方案似乎对我不起作用,或者与 Boost 序列化有关,但有些无关紧要。
以下是我的代码的简化版本(没有使用其他地方的编辑):
类(class)代码
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 ;
}
我敢肯定它不应该这么难。所以,我想我的问题是......我做错了什么?我现在应该从哪里开始阅读/研究?
最佳答案
我和你一样,已经搜索了很长时间关于如何序列化多态数据,你的问题提供的信息足以帮助我理解我的错误,并纠正你的错误。由于您的类没有完全实现,我提供了一个代码示例来实现您想要的。在我的例子中
#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;
}
//////////////////////////////////////////////////////////////////////
};
Parent 是您的Base
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;
}
//////////////////////////////////////////////////////////////////////
};
child 是您的派生
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;
}
我注意到您的 Derived 实际上并没有继承,这肯定会导致问题。另外,关键是如果你在一个类中有一个多态容器,那么你必须在那个类中注册每个派生类型(而不是在基类中)。请参阅上面的家庭类(class)。
希望对你有帮助。
关于c++ - 带 Boost 的多态序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17698267/