我正在尝试序列化指向多态类的指针Shape
。所以我需要使用BOOST_CLASS_EXPORT
宏来为每个子类定义一个 GUID。问题:放在哪里?
让我先展示一个最小的测试用例:
形状.hpp
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
class Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
// nothing to do
}
public:
virtual ~Shape() { }
};
class Rect : public Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
ar & boost::serialization::base_object<Shape>(*this);
}
public:
virtual ~Rect() { }
};
#ifdef EXPORT_IN_HEADER
BOOST_CLASS_EXPORT(Rect)
#endif
导出.cpp
#include <boost/serialization/export.hpp>
#include "shapes.hpp"
#ifdef EXPORT_IN_OBJECT
BOOST_CLASS_EXPORT(Rect)
#endif
主文件
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include "shapes.hpp"
#ifdef EXPORT_IN_MAIN
BOOST_CLASS_EXPORT(Rect)
#endif
int main() {
Shape *shape = new Rect();
boost::archive::text_oarchive ar(std::cout);
ar << shape;
}
在 gcc 上,我用
g++ -omain main.cpp export.cpp -Wl,-Bstatic -lboost_serialization-mt -Wl,-Bdynamic -DEXPORT_IN_XXX
在这里,export.cpp
可能看起来有点傻。在我的实际情况中,它包含一个使用 PIMPL 习语的封闭类,并尝试序列化其(多态)Shape
实现。重要的一点是:BOOST_CLASS_EXPORT
可能与调用序列化的代码位于不同的目标文件中。
那么问题来了:在哪里使用BOOST_CLASS_EXPORT
?我有三个选项,可以使用EXPORT_IN_XXX
宏启用。
EXPORT_IN_MAIN
有效,但不是我想要的。调用序列化的代码不需要知道 PIMPL 类的实现细节。EXPORT_IN_OBJECT
编译,但不起作用:它导致boost::archive::archive_exception
带有消息unregistered void cast
。根据文档,这应该通过boost::serialization::base_object
像我一样使用序列化基类来解决,但这没有帮助。EXPORT_IN_HEADER
甚至不编译。宏BOOST_CLASS_EXPORT
扩展为模板特化(我们希望在头文件中),但也扩展为其中静态成员的定义。所以我得到一个关于 a 的链接器错误multiple definition of 'boost::archive::detail::init_guid<Rect>::guid_initializer'
。
如果重要的话,我正在使用 g++ 4.4.3 和 Boost 1.40。