从接口序列化派生类
Serializing a derived class from an interface
新建:我可以从access.hpp使用这个吗?
template<class Archive, class T>
inline void serialize_adl(Archive &, T &, const unsigned int);
这表明我可以定义一个不同的序列化程序,将对象作为参数。
因此,以下代码更改是否有效?
我想我的问题是如何在接口类,它将调用派生的子类。
class Interface {
public:
virtual void aVirtual() = 0;
private:
friend class boost::serialization::access;
template<class Archive, class T>
void serialize_adl(Archive & ar, T & object, const unsigned int version)
{
// Would this work?????
ar & object;
}
};
template<class T>
class Derived : Interface {
public:
Derived(T in) : m_data(in) {}
virtual void aVirtual() { // Do something }
private:
T m_data;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & m_data;
}
};
我目前从我的编译器中得到以下错误:
error C2039: 'serialize' : is not a member of 'Interface'
这是不寻常的,因为对象在智能指针内,所以它应该知道它是什么类型:
std::unique_ptr<Interface> object = std::unique_ptr<Interface>(new Derived<int>(5));
因此,当我尝试序列化时:
archive >> *object;
因此我得到了错误。
这里有两个问题:
-
您正在序列化一个模板类。这不是问题,是的,你可以侵入性地(成员
serialize
)或非侵入性地进行(通过ADL的自由函数serialize
)。正如文档(序列化模板)所述,shared_ptr<T>
序列化的实现是非侵入性变体的一个很好的例子:- http://www.boost.org/doc/libs/release/boost/serialization/shared_ptr.hpp
-
您正在通过多态指针序列化基类/派生类。对于序列化部分,这没有什么特别的(您可以使用
register_type
,也可以在派生的serialize
函数中使用base_object<Interface>(this)
然而,在反序列化方面,您需要预测通过多态指针序列化的可能的具体实例类型的完整列表。
BOOST_EXPORT_CLASS
宏是实现这一点的最简单方法。不过,您必须列出您希望支持的模板的具体实例:BOOST_CLASS_EXPORT(Derived<std::string>) BOOST_CLASS_EXPORT(Derived<double>) BOOST_CLASS_EXPORT(Derived<int>) // include all subtypes we can expect in an input archive
或
BOOST_CLASS_EXPORT_GUID(Derived<std::string>, "4ef5a3ff-168a-4242-846b-4886f48424b5") BOOST_CLASS_EXPORT_GUID(Derived<double>, "d0ed9de6-584f-476d-9898-8234bcb4efdb") BOOST_CLASS_EXPORT_GUID(Derived<int>, "505538f0-2dd1-43bd-92a2-506ed9659bbe") // include all subtypes we can expect in an input archive
这种情况的复杂性和混乱源于您正在通过多态指针序列化派生的类模板。所有这些同时发生。但从概念上讲,两者都很容易解决。
稍不相关,
- 是的,您可以使用免费的函数序列化,请参阅下面的第三个替代版本。不过,它并没有给你带来什么好处,只是要求
m_data
可以公开访问- 不要使用
serialize_adl
,因为它是一个实现细节
以下是三个集成了所有内容的示例:
-
在Coliru上直播 -原始
Interface*
-
在Coliru上直播 -与
shared_ptr<Interface>
相同 -
在Coliru上直播 -与非侵入式
serialize
功能相同
第一个示例的列表
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <sstream>
class Interface {
public:
virtual void aVirtual() = 0;
virtual ~Interface() {}
private:
friend class boost::serialization::access;
template<class Archive> void serialize(Archive&, unsigned) { }
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(Interface)
template<class T>
class Derived : public Interface {
public:
Derived(T in = 0) : m_data(in) {}
virtual void aVirtual() { /*Do something*/ }
T const& getData() const { return m_data; }
private:
T m_data;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, unsigned)
{
ar & boost::serialization::base_object<Interface>(*this);
//// alternatively, if you don't want to make the abstract base serializable:
// boost::serialization::void_cast_register<Derived, Interface>();
ar & m_data;
}
};
BOOST_CLASS_EXPORT(Derived<std::string>)
BOOST_CLASS_EXPORT(Derived<double>)
BOOST_CLASS_EXPORT(Derived<int>) // include all subtypes we can expect in an input archive
int main()
{
std::stringstream ss;
{
boost::archive::text_oarchive oa(ss);
Interface* o = new Derived<int>(42);
oa << o;
delete o;
}
std::cout << "Serialized: '" << ss.str() << "'n";
{
boost::archive::text_iarchive ia(ss);
Interface* o = nullptr;
ia >> o;
if (auto p = dynamic_cast<Derived<int>*>(o))
std::cout << "Deserialized into Derived<int> with data: " << p->getData() << "n";
delete o;
}
}
样本输出:
Serialized: '22 serialization::archive 11 0 1 1 12 Derived<int> 1 0
0 42
'
Deserialized into Derived<int> with data: 42
好吧,也许这对你有帮助,或者我可能错了;但是在c++inherit中,没有一个机制可以调用子类的方法,因为一个类可以有很多子类,而超类没有子类的引用,因为从子类到超类的多态性函数是不可逆的。因此,可以从派生类开始调用超类的函数。
致以最良好的问候。
您应该只序列化派生对象。使用dynamic_cast进行类型转换
class Interface {
virtual void f() = 0;
};
template<class T> class Derived : public Interface {
T m_data; void f(){};
};
Interface* object = new Derived<Type>();
Derived<Type>* objectSer = dynamic_cast<Derived<Type>*>(object);
//serialization
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs); oa << *objectSer;
- boost::序列化中的派生类偏移量计算.有效吗?
- 从模板化类版本控制序列化派生类
- 使用 boost::序列化将派生类指针序列化为向量时出现问题
- 用基础和派生类编写虚拟序列化函数
- boost::serialization-序列化从泛型属性/功能容器派生的类
- 如何隔离派生类的数据(序列化)
- 派生对象的提升序列化不调用派生对象的序列化()
- Boost::序列化和Boost::mpi通过基类指针广播派生类
- 从接口序列化派生类
- dll内部定义的派生嵌套类的序列化
- 使用Boost:serialize反序列化指向派生类的指针时出现问题
- 派生类行程的序列化Boost断言
- 通过指向派生类的基本指针提升序列化
- 用于序列化的来自CObject的派生将导致访问时出现编译器错误
- Boost动态序列化所有派生类型
- 如何在c++中对派生类使用Boost序列化
- 在Boost (c++)中没有类跟踪的派生类序列化
- 对不同派生类的增强反序列化进行正确的类型转换
- 增强模板派生类的序列化
- 从结构列表派生的结构的boost序列化