デフォルトコンストラクタを持たないクラスをシリアライズする。
save_construct_dataを使う、とかいった情報は出てくるのに、肝心のアーカイブ化するサンプルコードが探した限りあんまり無いので、サンプル張っておきます。ここに知りたいことが書いてありました。
- 侵入型
#include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> class Hoge { public: Hoge(int d, double& r) : data_(d), ref_(r) {} int data() const { return data_; } double const& ref() const { return ref_; } private: friend boost::serialization::access; template <typename Archive> void serialize(Archive&, unsigned int) { // 何もしない } int data_; double& ref_; }; namespace boost { namespace serialization { template <typename Archive> void save_construct_data(Archive& ar, Hoge const* p, unsigned int) { auto const& d = p->data();// ar << xxxや、make_nvpは左辺値参照を引数に取るので、右辺値を左辺値に変換する必要が有る ar << boost::serialization::make_nvp("data", d); ar << boost::serialization::make_nvp("ref", p->ref()); } template <typename Archive> void load_construct_data(Archive& ar, Hoge* p, unsigned int) { int d; double* r = new double{};// ここで確保したメモリは手動で開放する必要があるので、shared_ptrとか使ったほうがいい ar >> boost::serialization::make_nvp("data", d); ar >> boost::serialization::make_nvp("ref", *r); ::new(p) Hoge(d, *r); } } } #include <fstream> #include <iostream> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> int main() { { double r = 3.14; Hoge h{42, r}; auto* p = &h; std::ofstream ofs{"hoge.xml"}; boost::archive::xml_oarchive oa{ofs}; oa << boost::serialization::make_nvp("Hoge", p); } { Hoge* p = nullptr; std::ifstream ifs{"hoge.xml"}; boost::archive::xml_iarchive ia{ifs}; ia >> boost::serialization::make_nvp("Hoge", p); std::cout << p->data() << ", " << p->ref() << std::endl; delete &(p->ref());// load_construct_dataで確保したメモリを開放する delete p; } }
- 非侵入型
#include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> class Hoge { public: Hoge(int d, double& r) : data_(d), ref_(r) {} int data() const { return data_; } double const& ref() const { return ref_; } private: int data_; double& ref_; }; namespace boost { namespace serialization { template <typename Archive> void serialize(Archive& ar, Hoge& hoge, unsigned int) { // 何もしない } template <typename Archive> void save_construct_data(Archive& ar, Hoge const* p, unsigned int) { auto const& d = p->data();// ar << xxxや、make_nvpは左辺値参照を引数に取るので、右辺値を左辺値に変換する必要が有る ar << boost::serialization::make_nvp("data", d); ar << boost::serialization::make_nvp("ref", p->ref()); } template <typename Archive> void load_construct_data(Archive& ar, Hoge* p, unsigned int) { int d; double* r = new double{};// ここで確保したメモリは手動で開放する必要があるので、shared_ptrとか使ったほうがいい ar >> boost::serialization::make_nvp("data", d); ar >> boost::serialization::make_nvp("ref", *r); ::new(p) Hoge(d, *r); } } } #include <fstream> #include <iostream> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> int main() { { double r = 3.14; Hoge h{42, r}; auto* p = &h; std::ofstream ofs{"hoge.xml"}; boost::archive::xml_oarchive oa{ofs}; oa << boost::serialization::make_nvp("Hoge", p); } { Hoge* p = nullptr; std::ifstream ifs{"hoge.xml"}; boost::archive::xml_iarchive ia{ifs}; ia >> boost::serialization::make_nvp("Hoge", p); std::cout << p->data() << ", " << p->ref() << std::endl; delete &(p->ref());// load_construct_dataで確保したメモリを開放する delete p; } }