boost::serialization

本文详细介绍了Boost.Serialization库的使用方法,包括基本数据类型的序列化、类成员的序列化、继承类的序列化等,并通过一个公交车路线系统的实例展示了如何在实际项目中应用Boost.Serialization。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://www.cnblogs.com/edwardlost/archive/2011/03/16/1984623.html


boost::serialization 基于 boost::archive 来完成任意复杂数据结构的序列化,boost::archive提供两个实现类来完成序列化、反序列化操作:

boost::archive::text_oarchive     序列化数据,也称为:输出、保存(save)

boost::archive::text_iarchive      反序列化数据,也称为:输入、载入(load)

也可以使用二进制格式:binary_oarchive, binary_iarchive

 

&操作符 

序列化操作使用 << 或者 & 操作符将数据存入text_oarchive中:

ar << data;
ar 
& data;

 

反序列化操作使用 >> 或者 & 操作符从text_iarchive中读取数据:

ar >> data;
ar 
& data;

为什么要引入&操作符?很简单,&操作符可以同时用于序列化和反序列化操作,这样就只需要提供一个 serialize 模板函数就可以同时用于两种操作,具体执行哪种由ar的类型(模版参数类型)决定;如果ar是text_oarchive类型则是序列化,如果ar是text_iarchive类型则是反序列化。

 

serialize模版函数 

基础简单数据类型直接使用&操作符就行了,class类型数据需要自定义serialize模板函数来序列化对象,序列化时serialize函数会被自动调用。

 

有两种方式来给class添加serialize接口,一种是成员函数方式(intrusive),另一种是非成员函数方式(non-intrusive)。这两种方式各有利弊:non-intrusive方式虽然不用修改class的定义,但要求class数据成员的访问属性为public,不过可以通过声明函数为friend来解决这个问题。

 

 成员函数方式(intrusive)

/**
 * GPS坐标点
 */
 class gps_position
 {
 private:
     friend class boost::serialization::access;
     
     //intrusive方式,该成员函数同时用于序列化和反序列化操作
     template<class Archive>
     void serialize(Archive & ar, const unsigned int version)
     {
         ar & degrees & minutes & seconds;
     }
 
     int degrees;
     int minutes;
     float seconds;
 
 public:
     gps_position(){};
     gps_position(int d, int m, float s) :
         degrees(d), minutes(m), seconds(s)
     {}
 };


 

非成员函数方式(non-intrusive) 

/**
 * GPS坐标点
 */
 class gps_position
 {
     //non-intrusive方式,定义友元模版函数
     template<class Archive>
     friend void serialize(Archive& ar, gps_position& g, const unsigned int version)
     {
         ar & g.degrees & g.minutes & g.seconds;
     }
 
 
 private:
     int degrees;
     int minutes;
     float seconds;
 
 public:
     gps_position(){};
     gps_position(int d, int m, float s) :
         degrees(d), minutes(m), seconds(s)
     {}
 };


 

 类成员序列化

 对类进行序列化要求所涉及的数据成员必须是可序列化的,即为:简单数据类型(POD)、数组类型、STL容器、或者实现了serialize接口的用户类。一个复合类类型实现了serialize接口后,就只需要将该类看做一个整体传给&操作符进行序列化,&操作符在序列化其数据成员时会自动调用相应的serialize接口进行处理。

/**
 * bus_stop类
 */
 class bus_stop
 {
     friend class boost::serialization::access;
 
     //只要数据成员类型是可序列化的就可以使用&操作符进行处理
     //可序列化的类型包括:基础的简单数据类型、数组类型、STL容器、或者实现了serialize接口的类
     template<class Archive>
     void serialize(Archive & ar, const unsigned int version)
     {
         ar & latitude & longitude;
     }
 
     gps_position latitude;        //serializable members
     gps_position longitude;
 
 protected:
     bus_stop(const gps_position & lat_, const gps_position & long_) :
     latitude(lat_), longitude(long_)
     {}
 
 public:
     bus_stop(){}
     
     virtual ~bus_stop(){}
 };


 

 编译程序

编译程序时需要带上库:-lboost_serialization


以下是boost官网自带的范例,非常全面

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo.cpp
//
// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)


#include <cstddef> // NULL
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>

#include <boost/archive/tmpdir.hpp>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/assume_abstract.hpp>

/////////////////////////////////////////////////////////////
// The intent of this program is to serve as a tutorial for
// users of the serialization package.  An attempt has been made
// to illustrate most of the facilities of the package.
//
// The intent is to create an example suffciently complete to
// illustrate the usage and utility of the package while
// including a minimum of other code.
//
// This illustration models the bus system of a small city.
// This includes, multiple bus stops,  bus routes and schedules.
// There are different kinds of stops.  Bus stops in general will
// will appear on multiple routes.  A schedule will include
// muliple trips on the same route.

/////////////////////////////////////////////////////////////
// gps coordinate
//
// llustrates serialization for a simple type
//
class gps_position
{
    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
    friend class boost::serialization::access;
    int degrees;
    int minutes;
    float seconds;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & degrees & minutes & seconds;
    }
public:
    // every serializable class needs a constructor
    gps_position(){};
    gps_position(int _d, int _m, float _s) :
        degrees(_d), minutes(_m), seconds(_s)
    {}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}

/////////////////////////////////////////////////////////////
// One bus stop
//
// illustrates serialization of serializable members
//

class bus_stop
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
    virtual std::string description() const = 0;
    gps_position latitude;
    gps_position longitude;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & latitude;
        ar & longitude;
    }
protected:
    bus_stop(const gps_position & _lat, const gps_position & _long) :
        latitude(_lat), longitude(_long)
    {}
public:
    bus_stop(){}
    virtual ~bus_stop(){}
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)

std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
{
    return os << bs.latitude << bs.longitude << ' ' << bs.description();
}

/////////////////////////////////////////////////////////////
// Several kinds of bus stops
//
// illustrates serialization of derived types
//
class bus_stop_corner : public bus_stop
{
    friend class boost::serialization::access;
    std::string street1;
    std::string street2;
    virtual std::string description() const
    {
        return street1 + " and " + street2;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // save/load base class information
        ar & boost::serialization::base_object<bus_stop>(*this);
        ar & street1 & street2;
    }

public:
    bus_stop_corner(){}
    bus_stop_corner(const gps_position & _lat, const gps_position & _long,
        const std::string & _s1, const std::string & _s2
    ) :
        bus_stop(_lat, _long), street1(_s1), street2(_s2)
    {
    }
};

class bus_stop_destination : public bus_stop
{
    friend class boost::serialization::access;
    std::string name;
    virtual std::string description() const
    {
        return name;
    }
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<bus_stop>(*this) & name;
    }
public:

    bus_stop_destination(){}
    bus_stop_destination(
        const gps_position & _lat, const gps_position & _long, const std::string & _name
    ) :
        bus_stop(_lat, _long), name(_name)
    {
    }
};

/////////////////////////////////////////////////////////////
// a bus route is a collection of bus stops
//
// illustrates serialization of STL collection templates.
//
// illustrates serialzation of polymorphic pointer (bus stop *);
//
// illustrates storage and recovery of shared pointers is correct
// and efficient.  That is objects pointed to by more than one
// pointer are stored only once.  In such cases only one such
// object is restored and pointers are restored to point to it
//
class bus_route
{
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
    typedef bus_stop * bus_stop_pointer;
    std::list<bus_stop_pointer> stops;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        // in this program, these classes are never serialized directly but rather
        // through a pointer to the base class bus_stop. So we need a way to be
        // sure that the archive contains information about these derived classes.
        //ar.template register_type<bus_stop_corner>();
        ar.register_type(static_cast<bus_stop_corner *>(NULL));
        //ar.template register_type<bus_stop_destination>();
        ar.register_type(static_cast<bus_stop_destination *>(NULL));
        // serialization of stl collections is already defined
        // in the header
        ar & stops;
    }
public:
    bus_route(){}
    void append(bus_stop *_bs)
    {
        stops.insert(stops.end(), _bs);
    }
};
std::ostream & operator<<(std::ostream &os, const bus_route &br)
{
    std::list<bus_stop *>::const_iterator it;
    // note: we're displaying the pointer to permit verification
    // that duplicated pointers are properly restored.
    for(it = br.stops.begin(); it != br.stops.end(); it++){
        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
    }
    return os;
}

/////////////////////////////////////////////////////////////
// a bus schedule is a collection of routes each with a starting time
//
// Illustrates serialization of STL objects(pair) in a non-intrusive way.
// See definition of operator<< <pair<F, S> >(ar, pair) and others in
// serialization.hpp
//
// illustrates nesting of serializable classes
//
// illustrates use of version number to automatically grandfather older
// versions of the same class.

class bus_schedule
{
public:
    // note: this structure was made public. because the friend declarations
    // didn't seem to work as expected.
    struct trip_info
    {
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version)
        {
            // in versions 2 or later
            if(file_version >= 2)
                // read the drivers name
                ar & driver;
            // all versions have the follwing info
            ar & hour & minute;
        }

        // starting time
        int hour;
        int minute;
        // only after system shipped was the driver's name added to the class
        std::string driver;

        trip_info(){}
        trip_info(int _h, int _m, const std::string &_d) :
            hour(_h), minute(_m), driver(_d)
        {}
    };
private:
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
    friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti);
    std::list<std::pair<trip_info, bus_route *> > schedule;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & schedule;
    }
public:
    void append(const std::string &_d, int _h, int _m, bus_route *_br)
    {
        schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
    }
    bus_schedule(){}
};
BOOST_CLASS_VERSION(bus_schedule::trip_info, 2)

std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
{
    return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
}
std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
{
    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);
    }
    return os;
}

void save_schedule(const bus_schedule &s, const char * filename){
    // make an archive
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << s;
}

void
restore_schedule(bus_schedule &s, const char * filename)
{
    // open the archive
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);

    // restore the schedule from the archive
    ia >> s;
}

int main(int argc, char *argv[])
{
    // make the schedule
    bus_schedule original_schedule;

    // fill in the data
    // make a few stops
    bus_stop *bs0 = new bus_stop_corner(
        gps_position(34, 135, 52.560f),
        gps_position(134, 22, 78.30f),
        "24th Street", "10th Avenue"
    );
    bus_stop *bs1 = new bus_stop_corner(
        gps_position(35, 137, 23.456f),
        gps_position(133, 35, 54.12f),
        "State street", "Cathedral Vista Lane"
    );
    bus_stop *bs2 = new bus_stop_destination(
        gps_position(35, 136, 15.456f),
        gps_position(133, 32, 15.300f),
        "White House"
    );
    bus_stop *bs3 = new bus_stop_destination(
        gps_position(35, 134, 48.789f),
        gps_position(133, 32, 16.230f),
        "Lincoln Memorial"
    );

    // make a  routes
    bus_route route0;
    route0.append(bs0);
    route0.append(bs1);
    route0.append(bs2);

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

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

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

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

    std::string filename(boost::archive::tmpdir());
    filename += "/demofile.txt";

    // save the schedule
    save_schedule(original_schedule, filename.c_str());

    // ... some time later
    // make  a new schedule
    bus_schedule new_schedule;

    restore_schedule(new_schedule, filename.c_str());

    // and display
    std::cout << "\nrestored schedule";
    std::cout << new_schedule;
    // should be the same as the old one. (except for the pointer values)

    delete bs0;
    delete bs1;
    delete bs2;
    delete bs3;
    return 0;
}



<think>好的,我现在遇到了一个关于Boost.Serialization的编译错误,具体是`boost::serialization::library_version_type`导致的“does not name a type”错误。我需要解决这个问题,首先得弄清楚错误的原因。 首先,用户提到错误信息是`'boost::serialization::library_version_type' does not name a type`。这说明编译器在查找这个类型时失败了。可能的原因有几个: 1. **头文件未包含**:可能没有包含必要的Boost.Serialization头文件。Boost库中的很多功能需要显式包含特定的头文件,特别是序列化相关的功能可能需要`boost/archive/text_oarchive.hpp`或者`boost/serialization/library_version_type.hpp`之类的头文件。 2. **命名空间错误**:虽然用户写的是`boost::serialization::library_version_type`,但有可能这个类型实际上位于另一个命名空间下,比如`boost::archive`。需要查阅Boost的文档确认正确的命名空间。 3. **Boost版本问题**:`library_version_type`可能是在较新的Boost版本中引入的,如果用户使用的是旧版本,可能没有这个类型。检查Boost的版本是否符合要求。 4. **序列化宏未正确使用**:如果在序列化类时没有正确使用BOOST_SERIALIZATION_SPLIT_MEMBER或其他相关宏,可能导致类型未正确声明。 接下来,我需要逐步验证这些可能性。首先,确保用户包含了正确的头文件。查阅Boost的文档,发现`library_version_type`确实属于`boost::serialization`命名空间,但可能需要包含`<boost/serialization/library_version_type.hpp>`头文件。不过,实际上在常见的序列化操作中,可能不需要直接包含这个头文件,而是通过其他头文件间接引入。例如,使用`boost/archive/text_oarchive.hpp`时会自动包含相关类型。 另外,检查Boost的版本。如果用户使用的是Boost 1.73或更高版本,`library_version_type`才被引入。如果版本过低,编译器自然找不到这个类型。用户需要升级Boost到至少1.73版本。 此外,检查代码中是否有拼写错误,比如命名空间或类型名的拼写错误。比如是否写成了`library_version_type`而不是其他类似的名字。 可能的解决步骤包括: 1. 包含必要的头文件,例如`#include <boost/serialization/library_version_type.hpp>`。 2. 检查Boost版本,确保其支持该类型。 3. 确认代码中的命名空间和类型名称正确无误。 4. 如果使用序列化宏,确保正确使用,如`BOOST_SERIALIZATION_SPLIT_MEMBER()`等。 另外,根据用户提供的引用内容,比如引用[4]提到CMake帮助管理外部库,可能需要检查项目的构建配置是否正确链接了Boost.Serialization库,确保CMake能够找到正确的Boost版本和组件。 最后,如果用户在使用Vcpkg安装Boost,可能需要重新安装或更新Boost库,确保安装的版本包含所需的类型。引用[3]中提到的Vcpkg安装CGAL,类似的方法可能适用于Boost的安装。</think>关于`boost::serialization::library_version_type`的编译错误“does not name a type”,以下是分步解决方案: ### 1. 检查头文件包含 确保代码中包含以下头文件: ```cpp #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/library_version_type.hpp> // 显式包含 ``` `library_version_type`可能需要显式包含其头文件,尤其是在较新的Boost版本中[^1]。 ### 2. 确认Boost版本 `library_version_type`在**Boost 1.73及以上版本**引入。通过以下命令检查版本: ```bash grep "#define BOOST_VERSION" /path/to/boost/version.hpp ``` 若版本低于1.73,需升级Boost: - **Vcpkg用户**:运行`vcpkg install boost --triplet=x64-windows`更新[^3]。 - **源码用户**:下载最新版本并重新编译。 ### 3. 验证命名空间和类型名称 确认代码中未混淆命名空间。例如: ```cpp // 正确用法 boost::serialization::library_version_type version; ``` 而非`boost::archive::library_version_type`。 ### 4. 检查序列化宏的使用 在序列化类时,需正确使用宏声明: ```cpp #include <boost/serialization/access.hpp> class MyClass { private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & data; } int data; }; ``` 若使用拆分序列化(save/load),需添加`BOOST_SERIALIZATION_SPLIT_MEMBER()`[^1]。 ### 5. 配置CMake确保正确链接 在`CMakeLists.txt`中,确保包含Boost.Serialization组件: ```cmake find_package(Boost REQUIRED COMPONENTS serialization) target_link_libraries(YourProject PRIVATE Boost::serialization) ``` 通过CMake管理依赖可避免路径问题[^4]。 ### 6. 重新生成构建环境 若使用Vcpkg或源码安装Boost后,需清理并重新生成构建缓存: ```bash rm -rf build/ && mkdir build && cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=[vcpkg路径]/scripts/buildsystems/vcpkg.cmake make ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值