これ使うとXMLの扱いがとっても簡単になりますね
基本的にはシリアライズしたいクラスのメンバにserialize関数を追加するだけです
・テキスト出力
#include <fstream> #include <string> #include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/text_oarchive.hpp> class Person { public: int age; std::string name; private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & age; archive & name; } }; int main() { std::ofstream ofs("C:/person.txt"); boost::archive::text_oarchive oarchive(ofs); Person person; person.age = 22; person.name = "Akira"; // クラス情報をテキスト出力 oarchive << static_cast<const Person&>(person); return 0; }
22 serialization::archive 4 0 0 22 5 Akira
・テキスト読込(↑で出力されたもの)
#include <iostream> #include <fstream> #include <string> #include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/text_iarchive.hpp> class Person { public: int age; std::string name; private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & age; archive & name; } }; int main() { std::ifstream ifs("C:/person.txt"); boost::archive::text_iarchive iarchive(ifs); // テキスト読込 Person person; iarchive >> person; // 読み込んだ内容を表示 std::cout << person.age << "," << person.name << std::endl; return 0; }
22,Akira
・XML出力
boost::serialization::make_nvpで要素名を指定する
それ以外はテキストと同じ
#include <fstream> #include <string> #include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/xml_oarchive.hpp> class Person { public: int age; std::string name; private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & boost::serialization::make_nvp("Age", age); archive & boost::serialization::make_nvp("Name", name); } }; int main() { std::ofstream ofs("C:/person.xml"); boost::archive::xml_oarchive oarchive(ofs); Person person; person.age = 22; person.name = "Akira"; // クラス情報をXML出力 oarchive << boost::serialization::make_nvp("Root", person); return 0; }
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="4"> <Root class_id="0" tracking_level="0" version="0"> <Age>22</Age> <Name>Akira</Name> </Root> </boost_serialization>
すばらしく簡単です。
これはもうC#並と言ってもいいのではないかと
(C#のは簡単すぎですね...ずるい)
・XML読込(↑で出力したもの)
#include <iostream> #include <fstream> #include <string> #include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/xml_iarchive.hpp> class Person { public: int age; std::string name; private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & boost::serialization::make_nvp("Age", age); archive & boost::serialization::make_nvp("Name", name); } }; int main() { std::ifstream ifs("C:/person.xml"); boost::archive::xml_iarchive iarchive(ifs); // XML読込 Person person; iarchive >> boost::serialization::make_nvp("Root", person); // 読み込んだ内容を表示 std::cout << person.age << "," << person.name << std::endl; return 0; }
・XML出力2(要素内要素があるもの...ツリー構造)
#include <fstream> #include <string> #include <boost/serialization/serialization.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/xml_oarchive.hpp> class Body { public: std::string heart; // 心臓 private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & boost::serialization::make_nvp("Heart", heart); } }; class Person { public: int age; // 年齢 std::string name; // 名前 Body body; // 体 private: friend class boost::serialization::access; template <class Archive> void serialize(Archive& archive, unsigned int version) { static_cast<void>(version); // No use archive & boost::serialization::make_nvp("Age", age); archive & boost::serialization::make_nvp("Name", name); archive & boost::serialization::make_nvp("Body", body); } }; int main() { std::ofstream ofs("C:/person.xml"); boost::archive::xml_oarchive oarchive(ofs); Person person; person.age = 22; person.name = "Akira"; person.body.heart = "heart"; // クラス情報をXML出力 oarchive << boost::serialization::make_nvp("Root", person); return 0; }
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="4"> <Root class_id="0" tracking_level="0" version="0"> <Age>22</Age> <Name>Akira</Name> <Body class_id="1" tracking_level="0" version="0"> <Heart>heart</Heart> </Body> </Root> </boost_serialization>
ただまァ、ルート要素(boost_serialization)だけジャマですね
以下は試してないですが
・書き込みと読み込みで違う動作をさせたい場合は、
serialize()ではなくsave()/load()をメンバ関数として作成する
・serialize()/save()/load()の引数versionとBOOST_CLASS_VERSIONを使用してバージョン管理が可能
std::list
std::map
std::set
std::basic_string
std::valarray
std::vector
std::pair
std::slist
std::hash_map
std::hash_set
boost::optional
boost::variant
boost::scoped_ptr
boost::shared_ptr
boost::weak_ptr