#include "boost/archive/text_iarchive.hpp"
#include "boost/archive/text_oarchive.hpp"
#include "boost/archive/binary_iarchive.hpp"
#include "boost/archive/binary_oarchive.hpp"
#include "boost/serialization/serialization.hpp"
#include "boost/serialization/vector.hpp"
#include "boost/serialization/shared_ptr.hpp"
#include <boost/serialization/export.hpp>
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <vector>
#include <memory>
#include <fstream>
#include <sstream>
std::stringstream ss;
std::ofstream ofs("data.txt");
std::ifstream ifs("data.txt");
using namespace boost::posix_time;
struct date{
friend class boost::serialization::access;
int year;
enum Month{Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
Month month;
int day;
template <class Archive>
void serialize(Archive &ar, const unsigned int version){
ar &year;
ar &month;
ar &day;
}
friend std::ostream& operator<<(std::ostream& os, const date& d){
os << d.year << "-" << d.month << "-" << d.day;
return os;
}
date(int y, Month m, int d):year(y),month(m),day(d){};
date(const date& d):year(d.year),month(d.month),day(d.day){};
date(){};
};
class Person{
std::size_t _id;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version){
std::cout<< "Person" <<std::endl;
ar &_id;
}
public:
std::size_t get_id(){
return _id;
}
explicit Person(std::size_t id):_id(id){};
Person(){};
};
class PersonInfo;
class Department{
std::vector<std::shared_ptr<PersonInfo>> _employers;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version){
ar &_employers;
}
public:
decltype(std::declval<std::vector<std::shared_ptr<PersonInfo>>>().push_back(std::shared_ptr<PersonInfo>())) // std::declval<T>() 是一个辅助函数,用于推断类型 T 的表达式,但它不会实际创建对象。
add_employer(std::shared_ptr<PersonInfo> e){
_employers.push_back(e);
};
std::vector<std::shared_ptr<PersonInfo>> get_employers(){
return _employers;
};
};
class PersonInfo : public Person{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version){
std::cout<< "PersonInfo" <<std::endl;
ar & boost::serialization::base_object<Person>(*this);
ar & _birth_day;
}
date _birth_day;
public:
explicit PersonInfo(std::size_t id, date d): Person(id), _birth_day(d){};
PersonInfo(){};
date get_birth_day(){
return _birth_day;
}
};
template<class T>
void save(T&& obj){
boost::archive::text_oarchive as(ofs);
as << obj;
}
template<class T>
T load(){
boost::archive::text_iarchive ia(ifs);
T p;
auto &pp = p;
ia >> pp;
return p;
}
int main(){
auto obj = std::make_shared<PersonInfo>(456, date(2024, date::Jan, 26));
auto obj1 = std::make_shared<PersonInfo>(123, date(2024, date::Jan, 26));
auto obj2 = std::make_shared<PersonInfo>(789, date(2024, date::Jan, 26));
Department soft;
soft.add_employer(obj);
soft.add_employer(obj1);
soft.add_employer(obj2);
save(soft);
auto ret = load<Department>();
for(auto& e : ret.get_employers()){
std::cout<< (std::static_pointer_cast<PersonInfo>(e))->get_birth_day() <<std::endl;
//std::cout<< e->get_id() <<std::endl;
}
}
遇到了一个问题,如果Department::_employers存的是基类指针,即使实际存入的是派生;类指针,序列化也只序列化基类的成员,没有序列化派生类的。例如:
class Person{
std::size_t _id;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version){
std::cout<< "Person" <<std::endl;
ar &_id;
}
....
};
class PersonInfo : public Person{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version){
std::cout<< "PersonInfo" <<std::endl;
ar & boost::serialization::base_object<Person>(*this);
ar & _birth_day;
}
....
};
class Department{
std::vector<std::shared_ptr<Person>> _employers;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version){
ar &_employers;
}
public:
decltype(std::declval<std::vector<std::shared_ptr<Person>>>().push_back(std::shared_ptr<Person>())) // std::declval<T>() 是一个辅助函数,用于推断类型 T 的表达式,但它不会实际创建对象。
add_employer(std::shared_ptr<Person> e){
_employers.push_back(e);
};
std::vector<std::shared_ptr<Person>> get_employers(){
return _employers;
};
};
int main(){
auto obj = std::make_shared<PersonInfo>(456, date(2024, date::Jan, 26));
auto obj1 = std::make_shared<PersonInfo>(123, date(2024, date::Jan, 26));
auto obj2 = std::make_shared<PersonInfo>(789, date(2024, date::Jan, 26));
Department soft;
soft.add_employer(obj);
soft.add_employer(obj1);
soft.add_employer(obj2);
save(soft);
auto ret = load<Department>();
for(auto& e : ret.get_employers()){
std::cout<< (std::static_pointer_cast<PersonInfo>(e))->get_birth_day() <<std::endl;
//std::cout<< e->get_id() <<std::endl;
}
/*************************
结果为
Person
Person
Person
Person
Person
Person
0-0-0
0-0-32
0-0-32
*****************************、
}
protobuf 序列化
syntax = "proto3";
message PersonPB {
string name = 1;
int32 id = 2;
int64 date = 3;
}
message PersonInfoPB {
PersonPB pb = 1;
string birth_day = 2;
}
message CompanyPB {
string name =1;
repeated PersonInfoPB people = 2;
}
CompanyPB company;
PersonPB* pb = new PersonPB();
pb->set_id(10);
pb->set_date(200);
pb->set_name("aaaaaa00");
if (pb->SerializeToString(&str)) {
std::cout << "Serialized string: " << str.c_str() << std::endl;
} else {
std::cerr << "Failed to serialize." << std::endl;
}
PersonPB* pb2 = new PersonPB();
pb2->ParseFromString(str);
std::cout<<pb2->id() << pb2->date() << pb2->name() <<std::endl;
company.set_name("leelen");
auto pi = company.add_people();
pi->set_birth_day("2024-10.10");
pi->set_allocated_pb(pb);
参考文献: