gpt4 book ai didi

c++ - 使用 Boost :serialize 反序列化指向派生类的指针时出现问题

转载 作者:行者123 更新时间:2023-11-30 00:57:10 28 4
gpt4 key购买 nike

我在尝试使用 boost serialize 反序列化指向派生类的指针时遇到一个奇怪的问题。我有一个基础,并在它们之外派生了保存/加载函数(非侵入式版本),但每次我尝试反序列化一个指针时,我都会得到“输入流错误”异常或“未注册类”异常。这是我所做的:

首先我定义我的类:

#include <fstream>
#include <iomanip>

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/archive_exception.hpp>
#include "boost/serialization/split_free.hpp"
#include "boost/serialization/export.hpp"
#include "boost/serialization/utility.hpp"
#include <boost/serialization/string.hpp>
#include <boost/serialization/binary_object.hpp>

class Base
{
public:
bool isEnabled;
Base();
virtual ~Base(){}
};
Base::Base()
{
isEnabled = 0;
}

class Derived : public Base
{

public:
Derived();
virtual ~Derived(){}
int layerHeight;
};
Derived::Derived():Base()
{}

然后我确定他们的特征是我需要的:

BOOST_CLASS_EXPORT_GUID(Base, "Base")
BOOST_SERIALIZATION_SPLIT_FREE(Base)
BOOST_CLASS_IS_WRAPPER(Base)
BOOST_CLASS_TRACKING(Base, boost::serialization::track_selectively)
BOOST_CLASS_IMPLEMENTATION(Base, boost::serialization::object_class_info)

BOOST_SERIALIZATION_SPLIT_FREE(Derived)
BOOST_CLASS_EXPORT_GUID(Derived, "Derived")
BOOST_CLASS_IS_WRAPPER(Derived)
BOOST_CLASS_IMPLEMENTATION(Derived, boost::serialization::object_class_info)
BOOST_CLASS_TRACKING(Derived, boost::serialization::track_selectively)

接下来我定义实际的保存/加载函数:

namespace boost {

namespace serialization {

template<class Archive>
void save(Archive & ar,const Base& obj, const unsigned int version)
{
bool isEnabled = obj.isEnabled;
ar << BOOST_SERIALIZATION_NVP(isEnabled);
}
template<class Archive>
void load(Archive & ar, Base& obj, const unsigned int version)
{
bool isEnabled;
ar >> BOOST_SERIALIZATION_NVP(isEnabled);
}
} // namespace serialization
} // namespace boost

namespace boost {
template<>
struct is_virtual_base_of<Base, Derived>: public mpl::true_ {};

namespace serialization {

template<class Archive>
void save(Archive & ar,const Derived& obj, const unsigned int version)
{
ar & boost::serialization::base_object<Base>(obj);
int height =obj.layerHeight;
ar << BOOST_SERIALIZATION_NVP(height);
}
template<class Archive>
void load(Archive & ar, Derived& obj, const unsigned int version)
{
ar.template register_type<Base>();
ar.template register_type<Derived>();
ar & boost::serialization::base_object<Base>(obj);
int height;
ar >> BOOST_SERIALIZATION_NVP(height);
}
} // namespace serialization
} // namespace boost

还有 2 个我从 Docs 借来的保存/加载助手

template <typename T>
void save_schedule(const T& s, const char * filename){
// make an archive
std::ofstream ofs(filename);
assert(ofs.good());
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(s);
}

template <typename T>
void restore_schedule(T &s, const char * filename)
{
// open the archive
std::ifstream ifs(filename);
assert(ifs.good());
boost::archive::xml_iarchive ia(ifs);
// restore the schedule from the archive
ia >> BOOST_SERIALIZATION_NVP(s);
}

最后 - 这是我尝试全部使用它的方式

int main(int argc, char *argv[])
{
Base* basePointer = new Base();
Base* objectPointer = new Derived();
Derived * secondObjectPointer = new Derived();
Derived justObject;

save_schedule(basePointer, "C:\\basePointer.xml");
save_schedule(objectPointer, "C:\\objectPointer.xml");
save_schedule(secondObjectPointer , "C:\\secondObjectPointer.xml");
save_schedule(justObject, "C:\\justObject.xml");

//this works OK
restore_schedule(basePointer, "C:\\basePointer.xml");

//this gives "Input Stream Error"
restore_schedule(objectPointer, "C:\\objectPointer.xml");

//this gives "Unregistered class"
restore_schedule(secondObjectPointer, "C:\\secondObjectPointer.xml");

//This works >__< But I need to serialize pointers so I cannot use this
restore_schedule(justObject, "C:\\justObject.xml");
}

我做错了什么?为什么我不能反序列化指向基类的指针以外的任何东西?

最佳答案

UPD::经过更多搜索后,我能够将我的问题追溯到这个答案:

boost serialization exception: unregistered class, serializing polymorphic base problem

替换

//original taken from Boost Docs
ar & boost::serialization::base_object<Base>(obj);

// taken from the link above (macro expanded)
ar & boost::serialization::make_nvp( BOOST_PP_STRINGIZE(obj),boost::serialization::base_object<Base >(obj));

确实解决了问题。

作为旁注 - 我发现了另一种可能出现并导致“流输入错误”的奇怪错误。它是这样工作的:

如果您的层次结构中甚至有一个构造函数可以初始化一个变量(任何变量)但没有 - 您将在尝试反序列化时遇到流输入错误。

如果类中没有变量 - 一切正常。但是即使有一个——你必须在那个类的构造函数中至少初始化一个变量!我不知道为什么这很重要,但这对我来说解决了一个主要问题。

关于c++ - 使用 Boost :serialize 反序列化指向派生类的指针时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8819510/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com