之前我的程序在完全填充后用于序列化整个std::multimap<Participant*, Connection*>
。这对于保存和恢复来说都很简单arc & _connections
。
但是这需要每个连接对象留在内存中。但我不需要这些对象用于其他任何序列化。因此,为了最大限度地减少内存消耗,它决定在创建后std::make_pair(connection->participant(), connection)
序列化。序列化完成后删除。
预期的multimap大小是已知的。
我想要的是手动序列化这些对,这样我就不需要改变反序列化代码了arc & _connections;
来自boost/serialization/collections_save_imp.hpp
我看到了
boost::serialization::save_construct_data_adl(
ar,
&(*it),
boost::serialization::version<BOOST_DEDUCED_TYPENAME Container::value_type>::value
);
ar << boost::serialization::make_nvp("item", *it++);
所以我需要使用像
这样的东西typedef std::pair<Participant*, Connection*> PairT;
ar << BOOST_SERIALIZATION_NVP(expected_size);
if(3 < ar.get_library_version()){// I don't really understand this magic number here
const unsigned int item_version = boost::serialization::version<PairT>::value;
ar << BOOST_SERIALIZATION_NVP(item_version);
}
PairT pair = std::make_pair(connection->participant(), connection);
boost::serialization::save_construct_data_adl(
ar,
pair,
boost::serialization::version<PairT>::value
);
ar << boost::serialization::make_nvp("item", pair);
delete connection;
我不确定应该怎么做。只是猜测。
答案 0 :(得分:0)
我看到你想要做什么,但我不推荐它,因为它很容易破坏。
例如,如果将存档更改为xml,则无法使用。如果您升级到更新版本
升级版本,它可能会破坏,可能很难调试。原因是
归档本身可以在start_save()
(例如,类id)中添加一些额外的数据,然后它
进行实际序列化并通过调用end_save()
结束。既然那些方法是
受保护,您不能使用它们以便携/稳定的方式“伪造”序列化。
您可以覆盖(特殊化)多图序列化,但这样只会让您访问 空容器,你必须使用一些技巧(如全局变量)来访问连接 要序列化的对象:
template<class Archive>
inline void save(Archive& ar, const MultimapT& map, const unsigned version) {
Connection* p = new Connection( global_data->get(i) );
}
您还必须反序列化您正在序列化的同一个对象,因此唯一干净的方法是为存档提供一个包含处理序列化的多图的对象。该对象可以是拥有地图的类或虚拟对象。但是,这需要对现有的反序列化代码进行一些更改:
ar << boost::serialization::make_nvp("map",Dummy(&_source));
// and
ar >> boost::serialization::make_nvp("map",Dummy(&_connections));
虚拟构造函数将获取指向生成连接所需对象的指针
(保存时)或指向multimap的指针(加载时)。然后可以生成虚拟save()
方法,
在load()
方法只是填充多重映射时,即时存储和删除连接对象。
当您动态生成对象时,必须禁用对象跟踪:
BOOST_CLASS_TRACKING(Connection, boost::serialization::track_never)
BOOST_CLASS_TRACKING(Participant, boost::serialization::track_never)
否则归档会检测到重复序列化相同的内存地址,并将创建对第一个对象的引用,而不是实际存储数据。
这是一个成员函数示例,用于演示包含multimap(虚拟或父类)的对象的序列化:
// class Foo {
template<typename Archive>
inline void save( Archive& ar, const unsigned version ) const {
size_t count = expected_count();
ar << BOOST_SERIALIZATION_NVP(count);
for( size_t i=0; i<count; ++i ) {
Connection* connection = make_connection(i);
PairT pair(connection->participant(), connection);
ar << boost::serialization::make_nvp("item", pair);
delete connection;
}
}
template<typename Archive>
inline void load( Archive& ar, const unsigned version ) {
size_t count=0;
ar >> BOOST_SERIALIZATION_NVP(count);
while( count-- ) {
PairT pair;
ar >> boost::serialization::make_nvp("item", pair);
_connections->insert(pair);
}
}
friend boost::serialization::access;
BOOST_SERIALIZATION_SPLIT_MEMBER() // split serialize() into save() and load()
// }
参考文献:intrusive/non-intrusive serialization,splitting save and load,object tracking