Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 推进序列化,按基类型加载存档类会给出错误的数据_C++_Serialization_Boost - Fatal编程技术网

C++ 推进序列化,按基类型加载存档类会给出错误的数据

C++ 推进序列化,按基类型加载存档类会给出错误的数据,c++,serialization,boost,C++,Serialization,Boost,在我将Boost的序列化库实现到项目中之前,我编写了一个示例程序来了解它,但是,我得到了一些无法解释的行为 在我的示例中,我有两个类:一个是泛型的BaseClass,一个是专门的DerivedClass(类似于我计划使用Boost)BaseClass只有一个成员,一个名为name的字符串,默认为“BaseClass”DerivedClass公开继承基类,将名称设置为其他内容,并拥有自己的唯一成员数据 在主程序中,我创建了一个DerivedClass,其中data设置为“special cool

在我将Boost的序列化库实现到项目中之前,我编写了一个示例程序来了解它,但是,我得到了一些无法解释的行为


在我的示例中,我有两个类:一个是泛型的
BaseClass
,一个是专门的
DerivedClass
(类似于我计划使用Boost)
BaseClass
只有一个成员,一个名为
name
的字符串,默认为“BaseClass”
DerivedClass
公开继承
基类
,将
名称
设置为其他内容,并拥有自己的唯一成员
数据

在主程序中,我创建了一个
DerivedClass
,其中
data
设置为“special cool stuff”,以及一个
BaseClass
,其中
name
设置为“regular stuff”。我用
boost::archive::text\u oarchive
将这两个对象写入一个文件,并将第一个对象
DerivedClass
读回两次(两次都重新创建
std::ifstream
)。第一次读回它时,我将它放在
基类*
中。调用
BaseClass::printData()
(一种打印
std::typeid
name
的虚拟方法)会打印以下内容:

 --- Storage done, now loading the first object as BaseClass --- 
9BaseClass: 0
接下来,当我将其作为
DerivedClass*
加载并调用
DerivedClass::printData()
(从
BaseClass
覆盖以将成员
数据
包含在输出中)时,正确打印:

 --- Storage done, now loading the first object as DerivedClass --- 
12DerivedClass: DerivedClass AND special cool stuff
查看我正在写入的文件,我看到:

22 serialization::archive 15 0 1 0
0 1 0
1 12 DerivedClass 18 special cool stuff 1
2 13 regular stuff
当我对原始的、预序列化的
DerivedClass
调用
BaseClass::printData()
时,我得到如下结果:

9BaseClass: DerivedClass
显然,
DerivedClass
存储正确。将其作为
基类加载以检查
名称
的操作有些混乱。我想不出为什么它会给我一个包含
0
std::string

我刚刚开始学习如何使用这个库,我在网上发现的大多数类似问题和文档都没有效果(例如,使用
BOOST\u EXPORT\u CLASS
BOOST\u CLASS\u TYPE\u INFO
,尽管很可能是我用错了它们)


这是我的密码:

main.cpp
#包括
#包括
#包括
#包括
#包括
#包括
#包括“baseclass.h”
#包括“derivedclass.h”
int main(){
BaseClass*testBase=新的基类(“常规的东西”);
DerivedClass*testDerivate=新的DerivedClass(“特别酷的东西”);
testDerivate->BaseClass::printData();

std::cout您没有加载与序列化相同的类型

因此,可以说:

Base* b = new Derived();
boost_out << b;
不能序列化
派生的*
并将其反序列化为
Base*
,反之亦然

因此,如果您知道接收代码必须支持所有派生类,请将其显式化并序列化
Base*

导出类型 要让反序列化端知道在反序列化多态基指针时可能遇到的派生类型集,请导出这些类型

  • 另见:

    在“a.hpp”中包括
    BOOST\u CLASS\u EXPORT
    头本身与其他序列化特性一样,在调用
    BOOST\u CLASS\u EXPORT
    之前,很难或不可能遵循上面关于包含存档头的规则。这可以通过在头声明和
    BOOST\u CLASS\u EXPORT\u执行中使用
    BOOST\u CLASS\u EXPORT\u键来解决类定义文件中的ENT

    […剪断…]

    在库代码中放置
    BOOST\u CLASS\u EXPORT
    无效,除非还包含存档类标题。。因此,在构建库时,应该包含他预期使用的所有存档类的所有标题。或者,可以仅包含Polymoprhic[sic]存档的标题

演示 查看它

  • main.cpp

    #include <iostream>
    #include <fstream>
    #include <string>
    
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/serialization/nvp.hpp>
    //#include <boost/serialization/export.hpp>
    
    #include "baseclass.h"
    #include "derivedclass.h"
    
    int main() {
        BaseClass* testBase = new BaseClass("regular stuff");
        BaseClass* testDerived = new DerivedClass("special cool stuff");
    
        std::cout << std::endl << " --- " << "Storing objects in the file 'output'..." << " --- " << std::endl;
    
        {
            std::ofstream output("storage");
            boost::archive::text_oarchive boost_out(output);
            boost_out << testBase << testDerived;
        }
    
        std::cout << std::endl << " --- " << "Storage done, now loading the first object as BaseClass" << " --- " << std::endl;
    
        {
            std::ifstream input("storage");
            BaseClass* b1;
            BaseClass* b2;
            boost::archive::text_iarchive boost_in(input);
            boost_in >> b1 >> b2;
    
            std::cout << "b1: "; b1->printData();
            std::cout << "b2: "; b2->printData();
        }
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    //#包括
    #包括“baseclass.h”
    #包括“derivedclass.h”
    int main(){
    BaseClass*testBase=新的基类(“常规的东西”);
    BaseClass*testDerived=新的DerivedClass(“特别酷的东西”);
    std::cout添加了演示
    
    #pragma once
    
    #include <string>
    #include <iostream>
    #include <typeinfo>
    
    #include <boost/serialization/base_object.hpp>
    #include <boost/serialization/access.hpp>
    
    #include "baseclass.h"
    
    class DerivedClass :  public BaseClass
    {
    public:
        DerivedClass() : BaseClass("DerivedClass") {}
        DerivedClass(std::string custom) : BaseClass("DerivedClass") {
            data = custom;
        }
    
        virtual ~DerivedClass() {}
    
        void printData() override {
            std::cout << typeid(*this).name() << ": " << name << " AND " << data << std::endl;
        }
    
    protected:
        std::string data;
    
    private:
        friend class boost::serialization::access;
    
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version) {
            ar & (boost::serialization::base_object<BaseClass>(*this));
            ar & (data);
        }
    };
    
    Base* b = new Derived();
    boost_out << b;
    
    Base* b = nullptr;
    boost_in >> b;
    
    #include <iostream>
    #include <fstream>
    #include <string>
    
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/serialization/nvp.hpp>
    //#include <boost/serialization/export.hpp>
    
    #include "baseclass.h"
    #include "derivedclass.h"
    
    int main() {
        BaseClass* testBase = new BaseClass("regular stuff");
        BaseClass* testDerived = new DerivedClass("special cool stuff");
    
        std::cout << std::endl << " --- " << "Storing objects in the file 'output'..." << " --- " << std::endl;
    
        {
            std::ofstream output("storage");
            boost::archive::text_oarchive boost_out(output);
            boost_out << testBase << testDerived;
        }
    
        std::cout << std::endl << " --- " << "Storage done, now loading the first object as BaseClass" << " --- " << std::endl;
    
        {
            std::ifstream input("storage");
            BaseClass* b1;
            BaseClass* b2;
            boost::archive::text_iarchive boost_in(input);
            boost_in >> b1 >> b2;
    
            std::cout << "b1: "; b1->printData();
            std::cout << "b2: "; b2->printData();
        }
    }
    
    #pragma once
    
    #include <string>
    #include <iostream>
    #include <typeinfo>
    
    #include <boost/serialization/access.hpp>
    #include <boost/serialization/nvp.hpp>
    #include <boost/serialization/export.hpp>
    
    class BaseClass
    {
    public:
        BaseClass() {
            name = "BaseClass";
        }
    
        BaseClass(std::string custom) {
            name = custom;
        }
    
        virtual ~BaseClass() {}
    
        virtual void printData() {
            std::cout << typeid(*this).name() << ": " << name << std::endl;   
        }
    
    protected:
        std::string name;
    
    private:    
        friend class boost::serialization::access;
    
        template<class Archive>
        void serialize(Archive & ar, unsigned) {
            ar & (name);
        }
    };
    
    BOOST_CLASS_EXPORT_KEY2(BaseClass, "BaseClass");
    
    #include "baseclass.h"
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    BOOST_CLASS_EXPORT_IMPLEMENT(BaseClass)
    
    #pragma once
    
    #include <string>
    #include <iostream>
    #include <typeinfo>
    
    #include <boost/serialization/base_object.hpp>
    #include <boost/serialization/access.hpp>
    #include <boost/serialization/export.hpp>
    
    #include "baseclass.h"
    
    class DerivedClass :  public BaseClass
    {
    public:
        DerivedClass() : BaseClass("DerivedClass") {}
        DerivedClass(std::string custom) : BaseClass("DerivedClass") {
            data = custom;
        }
    
        virtual ~DerivedClass() {}
    
        void printData() override {
            std::cout << typeid(*this).name() << ": " << name << " AND " << data << std::endl;
        }
    
    protected:
        std::string data;
    
    private:
        friend class boost::serialization::access;
    
        template<class Archive>
        void serialize(Archive & ar, unsigned) {
            ar & (boost::serialization::base_object<BaseClass>(*this));
            ar & (data);
        }
    };
    
    BOOST_CLASS_EXPORT_KEY2(DerivedClass, "DerivedClass");
    
    #include "derivedclass.h"
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    BOOST_CLASS_EXPORT_IMPLEMENT(DerivedClass)