注册一个没有默认构造函数的类型
Posted
技术标签:
【中文标题】注册一个没有默认构造函数的类型【英文标题】:Register a type with no default constructor 【发布时间】:2016-03-01 23:07:10 【问题描述】:我正在尝试序列化没有默认构造函数的派生类。我正在使用反序列化构造函数模式。我读到您必须注册派生类的类型,所以我在输出存档 (outputArchive.register_type<Point>();
) 中这样做。但是,当尝试使用输入存档注册相同的类型时,我收到一个编译器错误,提示 Point
没有默认构造函数(它没有)。在这种情况下我们该怎么办?
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/base_object.hpp>
#include <fstream>
class AbstractPoint
public:
virtual ~AbstractPoint()
virtual void DoSomething() = 0;
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
// do nothing
;
class Point : public AbstractPoint
public:
Point(const double data) : mData(data)
void DoSomething()
template<class TArchive>
Point(TArchive& archive)
archive >> *this;
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
// Without this, we get unregistered void cast
archive & boost::serialization::base_object<AbstractPoint>(*this);
archive & mData;
double mData;
;
int main()
std::shared_ptr<AbstractPoint> point(new Point(7.4));
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive.register_type<Point>();
outputArchive << point;
outputStream.close();
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
//inputArchive.register_type<Point>(); // Compiler error: no Point::Point()
std::shared_ptr<AbstractPoint> pointRead(new Point(inputArchive));
Point* castedPoint = dynamic_cast<Point*>(pointRead.get());
std::cout << "Data: " << castedPoint->mData << std::endl;
return 0;
【问题讨论】:
仅供参考,我将这个问题分为这里和***.com/questions/35753953/… 【参考方案1】:在一个类型没有默认构造函数的情况下,可以使用save_construct_data
和load_construct_data
。
请注意,这些将仅在通过指针进行序列化时适用(出于显而易见的原因)。
示例如下:boost serialization of non-default constructible types 和 more
【讨论】:
前几天我了解到 (***.com/questions/35722135/…) 我应该使用反序列化构造函数模式。所以你是说这种模式只在不序列化多态类型指针时才有效? @DavidDoria 您的问题代码和答案代码在我看来都是典型的 Boost 序列化代码。由于答案中所述的原因,问题代码已损坏。我很想说答案代码仍然是错误的(很难让它可靠地工作;我什至无法开始思考如何将它与容器的 Boost 序列化结合起来)。所以是的,那个答案没有回答你真正的问题,因为你当时问错了问题。 不使用save/load_construct_data
的要点是,如果您没有/想要一个指针,那么您不需要像拥有/想要一个指针那样“伪造”来做序列化。
@DavidDoria 我猜 Redux 是,Boost Serialization 真的不喜欢非默认构造。就像我说的那样,我知道像这样的“作弊”是如何起作用的,但它永远不会与框架发生冲突以上是关于注册一个没有默认构造函数的类型的主要内容,如果未能解决你的问题,请参考以下文章
使用杰克逊的 JSON 反序列化:没有找到适合类型的构造函数 - 可以提供默认构造函数或注释构造函数 [重复]