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

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

问题描述

我一直在读,交叉引用,最终没有找到一个连贯的例子和答案。我想要做的是pretty简单,但显然我失去了一些东西。在英语中,我有一个阶级结构具有两个抽象基(纯BB纯AA派生),我管理为:

 的std ::矢量< AA * GT;

我想序列含有这种载体的另一个对象。一切的除了的这个载体序列化很好,但一旦它得到的矢量,它抛出:

 抛出的一个实例的boost ::存档:: archive_exception终止后,被称为
  什么():未注册类 - 派生类没有注册或导出

我已经尝试了一些事情,包括事先明确注册父类型的系列化,前pressly声明抽象基类作为这种以'BOOST_SERIALIZATION_ASSUME_ABSTRACT'等。不过,我离开我唯独在运行时。

我想在记录上得到这个例子(和解决方案),以便其他人可以使用这个优秀的,如果有点不透明,图书馆。一旦这个例子是方的,我将它提交给升压系列化维护者无论是在FAQ或文件,包括他们认为合适的。

样code复制下面的问题:

  / *
    G ++ -Iinclude / -llib -lboost_serialization〜/桌面/ ser_ex.cpp -o STEST
* /
#包括LT&;升压/系列化/ serialization.hpp>
#包括LT&;升压/系列化/ nvp.hpp>
#包括LT&;升压/存档/ xml_oarchive.hpp>
#包括LT&;升压/系列化/ vector.hpp>#包括LT&;&iostream的GT;
#包括LT&;&的fstream GT;
#包括LT&;串GT;
#包括LT&;矢量>命名空间bser =的boost ::系列化;
AA级
{
上市:
    虚拟无效美孚()= 0;
    性病::字符串名称;    模板<类归档和GT;
    无效连载(归档和放大器; AR,无符号整型FILE_VERSION)
    {
        AR&安培; bser :: make_nvp(姓名,姓名);
    }
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(AA);类BB:公共AA
{
上市:
    虚拟无效美孚()= 0;
    虚拟无效巴()= 0;
    INT的事情;    模板<类归档和GT;
    无效连载(归档和放大器; AR,无符号整型FILE_VERSION)
    {
        ar.template register_type< AA>();
        AR&安培; bser :: base_object< AA>(*此);
        AR&安培; bser :: make_nvp(物的东西);
    }
};
BOOST_SERIALIZATION_ASSUME_ABSTRACT(BB);CC级:大众BB
{
上市:
    虚拟无效美孚(){}
    虚拟无效栏(){}
    INT otherThing;    模板<类归档和GT;
    无效连载(归档和放大器; AR,无符号整型FILE_VERSION)
    {
        ar.template register_type< BB>();
        AR&安培; bser :: base_object< BB>(*此);
        AR&安培; bser :: make_nvp(OtherThing,otherThing);
    }
};INT主(INT ARGC,字符常量*的argv [])
{
    常量标准::字符串的文件名(my.serialized);
    常量的std ::字符串键(AAVector);    的std ::矢量< AA *> VV;
    vv.push_back(新CC);    的std :: ofstream的outfilestream(filename.c_str()的std :: IOS ::二进制);
    提高::档案:: xml_oarchive out_archive(outfilestream);
    out_archive<<提高::系列化:: make_nvp(key.c_str(),VV);
    outfilestream.close();
}


解决方案

我这稍作修改工作:


  • 替换 AR&安培; bser :: base_object< AA>(*此); BB ::连载

      AR&安培; BOOST_SERIALIZATION_BASE_OBJECT_NVP(AA);


  • 替换 AR&安培; bser :: base_object< BB>(*此); CC ::连载

      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.

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

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