boost序列化异常:未注册的类,序列化多态性基础问题 [英] boost serialization exception: unregistered class, serializing polymorphic base problem

查看:958
本文介绍了boost序列化异常:未注册的类,序列化多态性基础问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读,交叉参考,最终没有找到一个一致的例子和答案。我想做的是很简单,但我显然缺少一些东西。在英语中,我有一个班级结构,有两个抽象基础(纯BB来自纯AA),我管理为:

 的std ::矢量< AA * GT; 

我想序列化另一个包含此向量的对象。一切除了,这个向量序列化了,但一旦到达向量,它会抛出:

 终止调用后抛出一个boost :: archive :: archive_exception的实例
what():未注册的类派生类未注册或导出

我已经尝试了一些事情,包括在序列化之前明确地注册父类型,明确地将基本抽象类声明为BOOST_SERIALIZATION_ASSUME_ABSTRACT等。但是,我离开了除了在运行时间外。



我想将这个例子(和解决方案)记录下来,以便其他人可以使用这个优秀的,如果有点不透明的库。一旦这个例子是平方的,我会将它提交给升级序列化维护者,以包含在他们认为合适的FAQ或文档中。



示例代码来复制问题以下:

  / * 
g ++ -Iinclude / -Llib -lboost_serialization〜/ Desktop / ser_ex.cpp -o stest
* /
#include< boost / serialization / serialization.hpp>
#include #include< boost / archive / xml_oarchive.hpp>
#include< boost / serialization / vector.hpp>

#include< iostream>
#include< fstream>
#include< string>
#include< vector>

命名空间bser = boost :: serialization;
class AA
{
public:
virtual void foo()= 0;
std :: string name;

template< class Archive>
void serialize(Archive& ar,unsigned int file_version)
{
ar& bser :: make_nvp(Name,name);
}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(AA);

class BB:public AA
{
public:
virtual void foo()= 0;
virtual void bar()= 0;
int东西

template< class Archive>
void serialize(Archive& ar,unsigned int file_version)
{
ar.template register_type< AA>();
ar& bser :: base_object< AA *(* this);
ar& bser :: make_nvp(Thing,东西);
}
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(BB);

class CC:public BB
{
public:
virtual void foo(){}
virtual void bar(){}
int otherThing;

template< class Archive>
void serialize(Archive& ar,unsigned int file_version)
{
ar.template register_type< BB>();
ar& bser :: base_object< BB *(* this);
ar& bser :: make_nvp(OtherThing,otherThing);
}
};

int main(int argc,char const * argv [])
{
const std :: string filename(my.serialized);
const std :: string key(AAVector);

std :: vector< AA *> VV;
vv.push_back(new CC);

std :: ofstream outfilestream(filename.c_str(),std :: ios :: binary);
boost :: archive :: xml_oarchive out_archive(outfilestream);
out_archive<<< boost :: serialization :: make_nvp(key.c_str(),vv);
outfilestream.close();
}


解决方案

次要修改:




  • 替换 ar& bser :: base_object< AA>(* this); in BB :: serialize with:

      ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(AA); 


  • 替换 ar& bser :: base_object< BB>(* this); in CC :: serialize with:

      ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(BB); 


  • 添加 BOOST_CLASS_EXPORT(CC) CC 定义后。有关说明,请参阅此文档部分



i've been reading, cross-referencing, and ultimately not finding a coherent example and answer. what i'm trying to do is pretty simple, but i'm clearly missing something. in english, i've got a class structure with two abstract bases (pure BB derives from pure AA), which i manage as a:

std::vector<AA*>

i'd like to serialize another object containing this vector. everything except this vector serializes fine, but once it gets to the vector, it throws:

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  unregistered class - derived class not registered or exported

i've tried a few things, including explicitly registering the parent types prior to serialization, expressly declaring the base abstract classes as such with 'BOOST_SERIALIZATION_ASSUME_ABSTRACT', etc. however, i'm left with the exception at runtime.

i'd like to get this example (and solution) on the record so others can use this excellent, if a little opaque, library. once this example is square, i'll submit it to the boost serialization maintainers to include in either the FAQ or documentation as they see fit.

sample code to replicate the problem below:

/*
    g++ -Iinclude/ -Llib -lboost_serialization ~/Desktop/ser_ex.cpp -o stest
*/
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

namespace bser = boost::serialization;
class AA
{
public:
    virtual void foo() = 0;
    std::string name;

    template<class Archive>
    void serialize(Archive & ar, unsigned int file_version)
    {
        ar & bser::make_nvp( "Name", name );
    }
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT( AA );

class BB : public AA
{
public:
    virtual void foo() = 0;
    virtual void bar() = 0;
    int thing;

    template<class Archive>
    void serialize(Archive & ar, unsigned int file_version)
    {
        ar.template register_type< AA >();
        ar & bser::base_object< AA >( *this );
        ar & bser::make_nvp( "Thing", thing );
    }
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT( BB );

class CC : public BB
{
public:
    virtual void foo() {}
    virtual void bar() {}
    int otherThing;

    template<class Archive>
    void serialize(Archive & ar, unsigned int file_version)
    {
        ar.template register_type< BB >();
        ar & bser::base_object< BB >( *this );
        ar & bser::make_nvp( "OtherThing", otherThing );
    }
};

int main (int argc, char const *argv[])
{
    const std::string filename( "my.serialized" );
    const std::string key( "AAVector" );

    std::vector< AA* > vv;
    vv.push_back( new CC );

    std::ofstream outfilestream( filename.c_str(), std::ios::binary );
    boost::archive::xml_oarchive out_archive( outfilestream );
    out_archive << boost::serialization::make_nvp( key.c_str(), vv );
    outfilestream.close();
}

解决方案

I got this to work with minor modifications :

  • Replace ar & bser::base_object< AA >( *this ); in BB::serialize with :

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(AA);
    

  • Replace ar & bser::base_object< BB >( *this ); in CC::serialize with :

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BB);
    

  • Add a BOOST_CLASS_EXPORT(CC) after CC definition. See this documentation section for an explanation.

这篇关于boost序列化异常:未注册的类,序列化多态性基础问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆