c++ - 派生类序列化 - 'unregistered class' 异常

标签 c++ serialization boost

试图让 boost 序列化工作。主要思想是拥有一个包含一些成员和一些派生类的基类,每个派生类都有自己的私有(private)成员以及基类成员。
这是我正在尝试做的最小版本:

class base {
    public:
        virtual void print() = 0;
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive &ar, const unsigned) {}
}

class derived20 : public base {
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive &ar, const unsigned) {
            boost::serialization::base_object<base>(*this);
            ar & var20;
        }
        
        int var20 = 20;
        
    public:
        void print() override { std::cout << var20 << std::endl; }
}

class derived40 : public base {
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive &ar, const unsigned) {
            boost::serialization::base_object<base>(*this);
            ar & var40;
        }
        
        int var40 = 40;
        
    public:
        void print() override { std::cout << var40 << std::endl; }
}

BOOST_CLASS_EXPORT(derived20)
BOOST_CLASS_EXPORT(derived40)
BOOST_CLASS_EXPORT(base)

int main(int argc, char **argv) {
    std::stringstream ss;
    
    boost::archive::text_oarchive ar(ss);
    auto d20 = new derived20();
    ar << d20;
    
    // prints:
    // 22 serialization:archive 15 0 1 0
    // 0 20
    std::cout << ss.str() << std::endl;
    
    boost::archive::text_iarchive iar(ss);
    base *b;
    iar >> b;
    b->print(); // Should print "20"
}
我收到了 archive_exception: unregistered class错误。
我到底做错了什么?

最佳答案

这是一种罕见的情况,auto可能会伤害:

auto d20 = new derived20();
ar << d20;
对比:
base *b;
iar >> b;
注意 d20derived20* ,而不是 base* .因此,您通过尝试反序列化包含另一种类型的存档中的类型来调用未定义的行为。
简单地改变它:
base* d20 = new derived20();
修复一切:

Also noticed that you forgot to actually serialize the base object.


Live on coliru
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/access.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>

class base {
    public:
        virtual void print() = 0;
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive & /*unused*/, unsigned /*unused*/) {}
};

class derived20 : public base {
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive &ar, unsigned /*unused*/) {
            ar & boost::serialization::base_object<base>(*this)
               & var20;
        }
        
        int var20 = 20;
        
    public:
        void print() override { std::cout << var20 << std::endl; }
};

class derived40 : public base {
    private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive &ar, const unsigned /*unused*/) {
            ar & boost::serialization::base_object<base>(*this)
               & var40;
        }
        
        int var40 = 40;
        
    public:
        void print() override { std::cout << var40 << std::endl; }
};

BOOST_CLASS_EXPORT(derived20)
BOOST_CLASS_EXPORT(derived40)
BOOST_CLASS_EXPORT(base)

int main() {
    std::stringstream ss;
    
    {
        boost::archive::text_oarchive ar(ss);
        base* d20 = new derived20();
        ar << d20;
    }
    
    // prints:
    // 22 serialization:archive 15 0 1 0
    // 0 20
    std::cout << ss.str() << std::endl;
    
    {
        boost::archive::text_iarchive iar(ss);
        base *b = nullptr;
        iar >> b;
        b->print(); // Should print "20"
    }
}
打印
22 serialization::archive 17 0 9 derived20 1 0
0 20

20

关于c++ - 派生类序列化 - 'unregistered class' 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63001619/

相关文章:

c++ - 在 CppUnit 中断言迭代器相等

c++ - 读取二进制文件留下一些字节未读

c++ - std::condition_variable_any 的 libc++ 实现

java - Apache Spark 数据集。 foreach 与 Aerospike 客户端

wpf - 需要序列化位图图像 silverlight

java - 为什么即使存在默认构造函数,Java 也会报错 "No Valid Constructor"?

c++ - 使用 Boost-Regex 将字符串解析为字符和数字

c++ - Boost shared_ptr 不会立即销毁对象

c++ g++ & boost, token "("之前缺少二元运算符

c++ - 从 Windows building .o 但不是 .a 交叉编译 Boost for GCC ARM (Linux)