使用虚拟继承使用Cereal对多态类进行序列化

时间:2015-08-27 10:11:10

标签: c++ inheritance serialization cereal

我正在尝试使用Cereal 1.1.2序列化和反序列化多态类(使用虚拟继承)。我收到了“访问冲突 - 没有RTTI数据!”异步,当我尝试在反序列化后将其向下转换为派生类。当我使用普通继承而不是虚拟继承时,它工作正常。我已经在Visual Studio 2013 Community Edition的项目设置中启用了RTTI(/ GR)。这是我的代码:

class Boogie
{
    friend class cereal::access;
    virtual void virtualFunction() {}
    int boogieInt = 3;
    template<class Archive>
    void serialize(Archive & archive)
    {
        archive(boogieInt);
    }
};

class Booga : virtual public Boogie
{
    friend class cereal::access;
public:
    void virtualFunction() {}
    int boogaInt = 2;
    template<class Archive>
    void serialize(Archive & archive)
    {
        archive(cereal::virtual_base_class<Boogie>(this), boogaInt);
    }
};

CEREAL_REGISTER_TYPE(Booga);

int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        {
            std::shared_ptr<Boogie> boogie = std::make_shared<Booga>();
            std::ofstream ofs("Booga.txt");
            cereal::BinaryOutputArchive archive(ofs);
            archive(boogie);
            ofs.close();
        }

        std::shared_ptr<Boogie> deBoogie;
        std::ifstream ifs("Booga.txt");
        cereal::BinaryInputArchive iarchive(ifs);
        iarchive(deBoogie);

        std::shared_ptr<Booga> outBooga = std::dynamic_pointer_cast<Booga>(deBoogie);

        std::cout << outBooga->boogaInt << std::endl;

        std::cin.get();
    }
    catch (std::exception e)
    {
        std::cout << "EXCEPTION" << std::endl;
        std::cout << e.what() << std::endl;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您的问题是您正在保存并加载不同类型 - 您的加载代码应该反映您的保存代码。

另请注意,您不需要在此处使用虚拟继承,因为您只从单个父类派生 - 有关详细信息,请参阅here。另外,请参阅我对您的帖子的评论,了解如何以RAII方式正确使用档案。

您的输出可以指定为:

std::shared_ptr<Boogie> data = std::make_shared<Booga>();
archive( data ); // data is actually a Booga but we hold it in a Boogie ptr

请注意,即使我分配了Boogie指针,我也已分配到Booga对象 - 这基本上是多态的整个点,除非您需要这样做,否则不要使用多态

现在当我们执行加载时,我们加载到我们序列化的相同类型:

std::shared_ptr<Boogie> data;
archive( data ); // data is actually a Booga object because of polymorphism

确保实际传递给归档的变量类型是相同的,无论它们实际上是由于多态而导致的。