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