【发布时间】:2018-07-17 20:25:56
【问题描述】:
在将 Boost 的序列化库实现到项目之前,我编写了一个示例程序来找出它的序列化库,但是,我得到了一些无法解释的行为。
在我的示例中,我有两个类:一个通用的 BaseClass 和一个专用的 DerivedClass(类似于我计划使用 Boost 的目的)。 BaseClass 只有一个成员,一个名为name 的字符串,默认为“BaseClass”。 DerivedClass 公开继承 BaseClass,将 name 设置为其他内容并拥有自己的唯一成员 data。
在主程序中,我创建了一个 DerivedClass 并将 data 设置为“特别酷的东西”,并创建一个 BaseClass 和 name “常规的东西”。我将这两个都写入带有boost::archive::text_oarchive 的文件,然后将第一个对象DerivedClass 读回两次(两次都重新创建std::ifstream)。第一次读回来,我把它放到BaseClass*。调用BaseClass::printData()(打印std::typeid 和name 的虚拟方法)会打印以下内容:
--- Storage done, now loading the first object as BaseClass ---
9BaseClass: 0
接下来,当我将其加载为 DerivedClass* 并调用 DerivedClass::printData()(已从 BaseClass 覆盖以在输出中包含成员 data)时,会正确打印:
--- 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 被正确存储。将其加载为BaseClass 以检查name 的事情搞砸了。我想不出它为什么会给我一个包含0 的std::string。
我刚刚开始学习如何使用这个库,我在网上找到的大多数类似问题和文档都没有效果(即,使用 BOOST_EXPORT_CLASS 或 BOOST_CLASS_TYPE_INFO,尽管它很可能是我用错了)。
这是我的代码:
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 "baseclass.h"
#include "derivedclass.h"
int main() {
BaseClass* testBase = new BaseClass("regular stuff");
DerivedClass* testDerivate = new DerivedClass("special cool stuff");
testDerivate->BaseClass::printData();
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 << (testDerivate);
testDerivate->printData();
boost_out << (testBase);
testBase->printData();
}
std::cout << std::endl << " --- " << "Storage done, now loading the first object as BaseClass" << " --- " << std::endl;
{
std::ifstream input("storage");
BaseClass* base;
boost::archive::text_iarchive boost_in(input);
boost_in >> (base);
base->printData();
input.close();
}
std::cout << std::endl << " --- " << "Storage done, now loading the first object as DerivedClass" << " --- " << std::endl;
{
std::ifstream input("storage");
DerivedClass* derive;
boost::archive::text_iarchive boost_in(input);
boost_in >> (derive);
derive->printData();
input.close();
}
return 0;
}
基类.h
#pragma once
#include <string>
#include <iostream>
#include <typeinfo>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.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, const unsigned int version) {
ar & (name);
}
};
派生类.hpp
#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);
}
};
对不起,如果这有点长,我想尽可能描述。我对使用 Boost 很陌生,而且我对 C++ 的经验并不丰富,所以即使你的代码中只有一些通用的 cmets,我也会很感激。
【问题讨论】:
标签: c++ serialization boost