boost序列化异常:未注册的类,序列化多态基本问题

时间:2010-12-13 18:11:41

标签: c++ exception serialization boost polymorphism

我一直在阅读,交叉引用,最终没有找到一个连贯的例子和答案。我想做的事情很简单,但我显然错过了一些东西。在英语中,我有一个带有两个抽象基础的类结构(纯BB来自纯AA),我管理的是:

std::vector<AA*>

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

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

我尝试了一些事情,包括在序列化之前显式注册父类型,用'BOOST_SERIALIZATION_ASSUME_ABSTRACT'等明确声明基本抽象类,但是,我在运行时留下了异常。

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

用于复制以下问题的示例代码:

/*
    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();
}

2 个答案:

答案 0 :(得分:6)

我对此进行了一些小修改:

  • ar & bser::base_object< AA >( *this );中的BB::serialize替换为:

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(AA);
    
  • ar & bser::base_object< BB >( *this );中的CC::serialize替换为:

    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BB);
    
  • BOOST_CLASS_EXPORT(CC)定义后添加CC。有关说明,请参阅this documentation section

答案 1 :(得分:0)

注册任何抽象库也不是正确的事情。否则,您将遇到反序列化的问题。您应该在派生类中注册派生类,而不是在派生类中注册抽象库。

这似乎只对反序列化很重要。

请参见deserialization from an abstract base fails for boost serialization