我不知道这是否正是您正在寻找的,这肯定是与您目前所拥有的不同的方法,所以 YMMV...但在过去我通过创建类型层次结构然后使用 Boost.Serialization 自动序列化/反序列化指向多态类型的指针的能力实现了类似的目标。这样做的好处是不必在 您的 代码中使用任何 RTTI(该库可能在后台执行 RTTI - 我不确定),但确实有一些缺点。
一方面,它确实使 IMO 的代码更加复杂。您可能正在处理代码中的类型,这些类型无法轻松修改或进入层次结构。您也可能不愿意承受多态性和堆分配的(相对较小的)性能损失。
这是一个或多或少完整的示例。访问者模式在这里很有用,因为您可能只需要对可能没有任何共同点的现有类型进行非常薄的包装:
#include <boost/serialization/export.hpp>
class Visitor;
class Base
{
public:
virtual ~Base() { }
virtual void accept(const Visitor & v) = 0;
protected:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive & ar, const unsigned int version)
{ }
};
/* specialization for one set of types */
class Type1 : public Base
{
public:
virtual ~Type1() { }
virtual void accept(const Visitor & v) { ... }
protected:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & boost::serialization::base_object<Base>(*this);
ar & m_dataType1;
ar & m_dataType2;
//etc...
}
//member data follows...
};
/* specialization for some other set of types */
class Type2 : public Base
{
public:
virtual ~Type2() { }
virtual void accept(const Visitor & v) { ... }
protected:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & boost::serialization::base_object<Base>(*this);
ar & m_dataType1;
ar & m_dataType2;
//etc...
}
};
BOOST_CLASS_EXPORT_GUID(Type1, "Type1")
BOOST_CLASS_EXPORT_GUID(Type2, "Type2")
BOOST_CLASS_EXPORT_GUID 需要向库“注册”派生类型,以便它可以在存档中唯一地标识它们。有关更完整的解释,请参阅this page上标题为“派生类对象的指针”的部分
现在您可以使用指向基类的指针进行序列化和反序列化(甚至可以使用shared_ptr ;),并使用访问者模式(或其他方法)在运行时通过多态访问数据,例如:
boost::shared_ptr<Base> p;
...
p.reset(new Type1(...));
archive << p;
p.reset(new Type2(...));
archive << p;
...
archive >> p; //p now points to a Type1
archive >> p; //p now points to a Type2
这个问题和答案也可能有用:Boost Serialization using polymorphic archives
希望这会有所帮助!
编辑:修复了我指向 Boost 文档的链接...