我正在尝试(de)序列化多态矢量,但在不同的尝试中存在不同的问题。事件的整个顺序是:
我有Class Derived(和DerivedB,DerivedC等),它派生自Class Base&一个类LotsOfBases,它包含一个虚拟基础向量。
虽然,我不知道这是如何导致这个问题的 - 我相信我的问题是因为来自服务器的Vector中的对象是按特定顺序(AAABBCCCCD),当他们回来时他们在随机顺序,可能有不同数量的派生类(ABABCDDDA)。
以下是我失败的尝试。使用下面的方法2,如果我幸运我可以来回发送信息(如果课程顺序保持不变),但是当课程类型改变顺序时,问题就会开始发生。
代码使用&编译/运行时错误:
编译时没有添加任何内容,但我得到了RunTime问题,因为Boost不知道哪个类是哪个...所以我试过了:
ar.template register_type<Derived>() ;
- Registering Class在RunTime调用时得到以下内容: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)
- 与6 iirc相同的错误。
上面没有链接的例子来自我在StackOverflow上的大约30个页面,这些页面相似,但是他们提供的解决方案对我来说似乎不起作用,或者与Boost序列化有关,但有些不相关。
以下是我的代码的缩写版本(没有从其他地方使用的编辑):
课程代码
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 ;
}
我确信它不应该那么困难。所以,我想我的问题是......我做错了什么?我现在应该在哪里开始阅读/研究?
答案 0 :(得分:3)
我和你一样,已经搜索了很多关于如何序列化多态数据的问题,而且你的问题足以帮助我理解我的错误并纠正你的错误。由于您的类没有完全实现,我提供了一个代码示例,可以实现您想要的。在我的例子中
#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;
}
我注意到你的Derived实际上并没有继承,这肯定会导致问题。此外,关键是如果类中有多态容器,则必须在该类中注册每个派生类型(而不是在基类中)。请参阅上面的我的家庭课。
希望这会对你有所帮助。