boost 序列化

#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);

参考文献:

Highscore - Boost C++ 库 - 序列化

[翻译] ProtoBuf 官方文档(二)- 语法指引(proto2) - 简书 (jianshu.com)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值