微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用Boost库反序列化并获得会员价值

如何解决如何使用Boost库反序列化并获得会员价值

首先,我想告诉你

  1. 我是序列化技术的新手
  2. 我并不是完全不使用Boost序列化,但是我所经历的大多数示例都是非常直接的(例如,只有一个类,最多一个基类和一个派生类)。

我以here为例。在这里代码的编写者通过使用类save使用了loadbus_schedule函数。我遇到了在这里称为new_schedule的对象的帮助下获取所有成员变量的问题。我假设这个对象将帮助我获取其他类的所有成员(也许在这一点上我完全错了。)

除此之外,我已经看到,大多数成员变量都在private处,这意味着我无法从main函数访问它们。这就是为什么,我设置了一些getter函数来返回一些成员值。例如,从bus_schedule类开始,如果我可以返回schedule列表,则可以访问trip_info结构值以及类型为bus_route的指针。

返回我使用过的schedule列表的函数是:

std::list<std::pair<trip_info,bus_route *> >  return_schedule()
     {
         return schedule;
     }

main函数中,我使用了:

bus_schedule new_schedule;
auto returning_schedule = new_schedule.return_schedule();
for(auto i:returning_schedule)
    {
        cout<<(i.first)<<" ~~~~~~~ "<<(i.second)<<endl;
       /*with i.first I can access the struct info,i.second pointer gives me the info of
       bus_route pointer value ater dereferencing*/
    }

但是在这里,我仍然坚持从i.second指针获取单独的值。我在这里知道,bus_route类有一个名为stops的列表。 Here也返回了此内容。但是在我看来,每次进行这种反向计算都是很麻烦的。

我的问题是,在反序列化之后,是否有从boost直接获得所有成员变量的结果?我将为所有班级设置getter函数,但害怕找到使用这些函数的途径。

解决方法

这个问题实际上与序列化是分开的。这里没有任何序列化的东西提炼到数据结构。我对代码进行了现代化处理,以使用C ++ 17功能

  • auto并移动语义
  • default个特殊成员
  • [[nodiscard]]override虚拟关键字
  • 显式构造函数和emplace
  • 带解构的范围循环
  • make_unique<>而不是new / delete
  • 扩展的聚合初始化程序

总而言之,它使代码更短,更简单,更有效¹。另外,它突出显示了您想知道的一些内容,我将在下面显示。

Live On Coliru

#include <iostream>
#include <list>
#include <memory>
#include <string>

struct gps_position {
    int degrees;
    int minutes;
    float seconds;

    friend std::ostream& operator<<(std::ostream& os,const gps_position& gp) {
        return os << ' ' << gp.degrees << "º" << gp.minutes << "'" << gp.seconds << '"';
    }
};

/////////////////////////////////////////////////////////////
// One bus stop
struct bus_stop {
    gps_position latitude,longitude;

    [[nodiscard]] virtual std::string description() const = 0;
    virtual ~bus_stop() = default;
    friend std::ostream& operator<<(std::ostream& os,const bus_stop& bs) {
        return os << bs.latitude << bs.longitude << ' ' << bs.description();
    }

  protected:
    explicit bus_stop(gps_position _lat,gps_position _long)
            : latitude(_lat),longitude(_long) {}
};

/////////////////////////////////////////////////////////////
// Several kinds of bus stops
struct bus_stop_corner : bus_stop {
    std::string street1,street2;
    [[nodiscard]] std::string description() const override {
        return street1 + " and " + street2;
    }

    explicit bus_stop_corner(gps_position _lat,gps_position _long,std::string _s1,std::string _s2)
        : bus_stop(_lat,_long),street1(std::move(_s1)),street2(std::move(_s2)) {}
};

struct bus_stop_destination : bus_stop {
    std::string name;
    [[nodiscard]] std::string description() const override { return name; }

    bus_stop_destination(gps_position _lat,std::string _name)
        : bus_stop(_lat,name(std::move(_name)) {}
};

struct bus_route {
    using bus_stop_pointer = bus_stop*;
    std::list<bus_stop_pointer> stops;

    void append(bus_stop* _bs) { stops.insert(stops.end(),_bs); }
    friend std::ostream& operator<<(std::ostream& os,const bus_route& br) {
        for (auto& stop : br.stops) {
            os << '\n' << std::hex << "0x" << stop << std::dec << ' ' << *stop;
        }
        return os;
    }
};

/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
struct bus_schedule {
    struct trip_info { int hour,minute; std::string driver; };

    void append(const std::string& _d,int _h,int _m,bus_route* _br) {
        schedule.emplace(schedule.end(),trip_info{_h,_m,_d},_br);
    }

  private:
    friend std::ostream& operator<<(std::ostream& os,const bus_schedule& bs) {
        for (auto const& [k,v] : bs.schedule) { os << k << *v; }
        return os;
    }
    friend std::ostream& operator<<(std::ostream& os,const bus_schedule::trip_info& ti) {
        return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
    }
    std::list<std::pair<trip_info,bus_route*>> schedule;
};

int main() {
    // fill in the data
    // make a few stops
    auto bs0 = std::make_unique<bus_stop_corner>(
        gps_position{ 34,135,52.560F },gps_position{ 134,22,78.30F },"24th Street","10th Avenue");
    auto bs1 = std::make_unique<bus_stop_corner>(
        gps_position{ 35,137,23.456F },gps_position{ 133,35,54.12F },"State street","Cathedral Vista Lane");
    auto bs2 = std::make_unique<bus_stop_destination>(
        gps_position{ 35,136,15.456F },32,15.300F },"White House");
    auto bs3 = std::make_unique<bus_stop_destination>(
        gps_position{ 35,134,48.789F },16.230F },"Lincoln Memorial");

    // make the schedule
    bus_schedule original_schedule;
    bus_route route0;

    bus_route route1;

    {
        // make a route
        route0.append(bs0.get());
        route0.append(bs1.get());
        route0.append(bs2.get());

        // add trips to schedule
        original_schedule.append("bob",6,24,&route0);
        original_schedule.append("bob",9,57,&route0);
        original_schedule.append("alice",11,2,&route0);
    }

    {
        // make aother routes
        route1.append(bs3.get());
        route1.append(bs2.get());
        route1.append(bs1.get());

        // add trips to schedule
        original_schedule.append("ted",7,17,&route1);
        original_schedule.append("ted",38,&route1);
        original_schedule.append("alice",47,&route1);
    }

    // display the complete schedule
    std::cout << "schedule" << original_schedule;
}

打印:

schedule
6:24 bob 
 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane
 35º136'15.456" 133º32'15.3" White House
9:57 bob 
 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane
 35º136'15.456" 133º32'15.3" White House
11:2 alice 
 34º135'52.56" 134º22'78.3" 24th Street and 10th Avenue
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane
 35º136'15.456" 133º32'15.3" White House
7:17 ted 
 35º134'48.789" 133º32'16.23" Lincoln Memorial
 35º136'15.456" 133º32'15.3" White House
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane
9:38 ted 
 35º134'48.789" 133º32'16.23" Lincoln Memorial
 35º136'15.456" 133º32'15.3" White House
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane
11:47 alice 
 35º134'48.789" 133º32'16.23" Lincoln Memorial
 35º136'15.456" 133º32'15.3" White House
 35º137'23.456" 133º35'54.12" State street and Cathedral Vista Lane

结论

要方便地使用map数据结构,可以使用循环as the example has it

std::list<
    std::pair<bus_schedule::trip_info,bus_route*>>::const_iterator it;
for (it = bs.schedule.begin(); it != bs.schedule.end(); it++) {
    os << it->first << *(it->second);
}

但是,在C ++ 17中,您编写的内容与以下内容完全相同:

for (auto const& [info,route] : bs.schedule) { os << info << *route; }

您会看到[k,v]使用结构化绑定来提取值类型的“第一”和“第二”部分。如果编译器中没有C ++ 17功能,则始终可以手动执行以下操作:

for (auto const& pair : bs.schedule) {
    trip_info const& info = pair.first;
    bus_route const& route = *pair.second;
    os << info << route;
}

四处逛逛private成员

我认为该数据结构不是典型的或“良好”的惯用C ++。使用原始指针会引发内存管理错误(例如,反序列化路由的每个停站都会泄漏)。

在此“陷阱”中使用吸气剂/阻气剂的风险为putting lipstick on a pig²。

我会选择将您需要的内容公开。这是一个示例,该示例可从main中打印所有细节,而不会重载operator<<运算符:

// display the complete schedule
std::cout << "schedule";
for (auto const& [info,route] : original_schedule.schedule) {
    std::cout << '\n' << info.hour << ':' << info.minute << ' ' << info.driver << ' ';
    for (auto& stop : route->stops)
        std::cout << '\n' << stop->latitude << stop->longitude << ' ' << stop->description();
}

与以前一样打印。

完整列表

Live On Coliru

#include <iostream>
#include <list>
#include <memory>
#include <string>

struct gps_position {
    int degrees;
    int minutes;
    float seconds;

    friend std::ostream& operator<<(std::ostream& os,longitude;

    [[nodiscard]] virtual std::string description() const = 0;
    virtual ~bus_stop() = default;

    explicit bus_stop(gps_position _lat,name(std::move(_name)) {}
};

struct bus_route {
    std::list<bus_stop*> stops;
    void append(bus_stop* _bs) { stops.push_back(_bs); }
};

/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
struct bus_schedule {
    struct trip_info { int hour,_br);
    }

    std::list<std::pair<trip_info,&route1);
    }

    // display the complete schedule
    std::cout << "schedule";
    for (auto const& [info,route] : original_schedule.schedule) {
        std::cout << '\n' << info.hour << ':' << info.minute << ' ' << info.driver << ' ';
        for (auto& stop : route->stops)
            std::cout << '\n' << stop->latitude << stop->longitude << ' ' << stop->description();
    }
}

请注意,即使removing all blank lines and comments,and using the same formatting,代码也比示例短100行代码。


¹注意,该代码显然没有客观地“高效”,因为它可以进行所有形式的动态分配和运行时多态性

²这种反模式对于具有传统OOP背景的人来说很常见,请参见pseudo/quasi-classes(PDF)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?