Boost.Serialization 検証 ポインタメンバのシリアライズ

公開:2006-01-13 06:15
更新:2020-02-15 04:36
カテゴリ:boost,windows,c++

/*
Serializeのお勉強
オブジェクトが複数のポインタメンバで参照されている場合もきちんとシリ
アライズ、再構築ができるか?
結果:
できる。しかし、ポインタメンバのシリアライズの順序が1番目のものが実
体となり、2番目以降にシリアライズされたものが参照となる点に注意する。
必ずしも、プログラムで生成された順序で実体、参照と判断されるわけでは
ない。
オブジェクトの所有権が問題となる場合はシリアライズ順序に気をつけなけ
ればならない。
*/
#include <iostream>
#include <fstream>
#include <string>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/nvp.hpp>
//using namespace std;
struct a {
friend class boost::serialization::access;
a() : m_str("") {}
a(std::string& str) : m_str(str){}
std::string& str(){return m_str;}
private:
std::string m_str;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(m_str);
}
};
struct b {
friend class boost::serialization::access;
b(){ma = new a();}
b(std::string& s) {ma = new a(s);}
~b(){delete ma;}
a* pa(){return ma;};
private:
a* ma;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(ma);
}
};
struct c {
friend class boost::serialization::access;
c() {};
c(a* v){ma = v;};
~c(){}
a* pa() {return ma;};
private:
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(ma);
}
a* ma;
};
int main()
{
{   // シリアライズ
std::string s_ = "def";
b b_(s_);
c c_(b_.pa());
std::ofstream ofs("output.xml");
boost::archive::xml_oarchive oa(ofs);
// わざと逆順に保存
oa & BOOST_SERIALIZATION_NVP(c_);
oa & BOOST_SERIALIZATION_NVP(b_);
}
/* 生成されるXML
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="3">
<c_ class_id="0" tracking_level="0" version="0">
<ma class_id="1" tracking_level="1" version="0" object_id="_0">
<m_str>def</m_str>
</ma>
</c_>
<b_ class_id="2" tracking_level="0" version="0">
<ma class_id_reference="1" object_id_reference="_0"></ma>
</b_>
</boost_serialization>
*/
{   // 再構築
b b_;
c c_;
std::ifstream ofs("output.xml");
boost::archive::xml_iarchive oa(ofs);
oa & BOOST_SERIALIZATION_NVP(c_);
oa & BOOST_SERIALIZATION_NVP(b_);
//
std::cout << "b: string member is " << b_.pa()->str() << std::endl;
std::cout << "c: string member is " << c_.pa()->str() << std::endl;
}
}