網(wǎng)站首頁 編程語言 正文
一、說明
對Boost.Serialization庫的應用,存在如下內(nèi)容:
- Archive
- Pointers and References
- Serialization of Class Hierarchy Objects
- Wrapper Functions for Optimization
Boost.Serialization 庫可以將 C++ 程序中的對象轉(zhuǎn)換為可以保存和加載以恢復對象的字節(jié)序列。有不同的數(shù)據(jù)格式可用于定義生成字節(jié)序列的規(guī)則。 Boost.Serialization 支持的所有格式僅適用于此庫。例如,為 Boost.Serialization 開發(fā)的 XML 格式不應用于與不使用 Boost.Serialization 的程序交換數(shù)據(jù)。 XML 格式的唯一優(yōu)點是它可以使調(diào)試更容易,因為 C++ 對象以可讀格式保存。
二、關(guān)于Archive庫
Boost.Serialization 的主要概念是存檔。存檔是表示序列化 C++ 對象的字節(jié)序列。可以將對象添加到存檔中以對其進行序列化,然后再從存檔中加載。為了恢復以前保存的 C++ 對象,假定相同的類型。
示例 64.1。使用 boost::archive::text_oarchive
#include <boost/archive/text_oarchive.hpp>
#include <iostream>
using namespace boost::archive;
int main()
{
text_oarchive oa{std::cout};
int i = 1;
oa << i;
}
Boost.Serialization 提供歸檔類,例如 boost::archive::text_oarchive,它在 boost/archive/text_oarchive.hpp 中定義。此類可以將對象序列化為文本流。使用 Boost 1.56.0,示例 64.1 將 22 serialization::archive 11 1 寫入標準輸出流。
可以看出,boost::archive::text_oarchive 類型的對象 oa 可以像流一樣使用 operator<< 序列化變量。但是,不應將存檔視為存儲任意數(shù)據(jù)的常規(guī)流。要恢復數(shù)據(jù),您必須在存儲數(shù)據(jù)時訪問它,并以相同的順序使用相同的數(shù)據(jù)類型。示例 64.2 序列化并恢復一個 int 類型的變量。
示例 64.2。使用 boost::archive::text_iarchive
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <fstream>
using namespace boost::archive;
void save()
{
std::ofstream file{"archive.txt"};
text_oarchive oa{file};
int i = 1;
oa << i;
}
void load()
{
std::ifstream file{"archive.txt"};
text_iarchive ia{file};
int i = 0;
ia >> i;
std::cout << i << '\n';
}
int main()
{
save();
load();
}
boost::archive::text_oarchive 類將數(shù)據(jù)序列化為文本流,而 boost::archive::text_iarchive 類從此類文本流中恢復數(shù)據(jù)。要使用這些類,請包含頭文件 boost/archive/text_iarchive.hpp 和 boost/archive/text_oarchive.hpp。
檔案的構(gòu)造函數(shù)期望輸入或輸出流作為參數(shù)。流用于序列化或恢復數(shù)據(jù)。雖然示例 64.2 訪問文件,但也可以使用其他流,例如字符串流。
示例 64.3。使用字符串流序列化
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>
using namespace boost::archive;
std::stringstream ss;
void save()
{
text_oarchive oa{ss};
int i = 1;
oa << i;
}
void load()
{
text_iarchive ia{ss};
int i = 0;
ia >> i;
std::cout << i << '\n';
}
int main()
{
save();
load();
}
Example?64.3
示例 64.3 使用字符串流將 1 寫入標準輸出以序列化數(shù)據(jù)。
到目前為止,只有原始類型被序列化。示例 64.4 顯示了如何序列化用戶定義類型的對象。
示例 64.4。使用成員函數(shù)序列化用戶定義的類型
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>
using namespace boost::archive;
std::stringstream ss;
class animal
{
public:
animal() = default;
animal(int legs) : legs_{legs} {}
int legs() const { return legs_; }
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive &ar, const unsigned int version) { ar & legs_; }
int legs_;
};
void save()
{
text_oarchive oa{ss};
animal a{4};
oa << a;
}
void load()
{
text_iarchive ia{ss};
animal a;
ia >> a;
std::cout << a.legs() << '\n';
}
int main()
{
save();
load();
}
為了序列化用戶定義類型的對象,您必須定義成員函數(shù) serialize()。當對象被序列化為字節(jié)流或從字節(jié)流恢復時調(diào)用此函數(shù)。因為 serialize() 用于序列化和恢復,所以除了 operator<< 和 operator>> 之外,Boost.Serialization 還支持運算符 operator&。使用 operator& 時,無需在 serialize() 中區(qū)分序列化和恢復。
序列化或恢復對象時,會自動調(diào)用 serialize()。它永遠不應該被顯式調(diào)用,因此應該被聲明為私有的。如果聲明為私有,則必須將類 boost::serialization::access 聲明為友元,以允許 Boost.Serialization 訪問成員函數(shù)。
可能存在不允許修改現(xiàn)有類以添加 serialize() 的情況。例如,標準庫中的類就是如此。
示例 64.5。使用獨立函數(shù)序列化
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>
using namespace boost::archive;
std::stringstream ss;
struct animal
{
int legs_;
animal() = default;
animal(int legs) : legs_{legs} {}
int legs() const { return legs_; }
};
template <typename Archive>
void serialize(Archive &ar, animal &a, const unsigned int version)
{
ar & a.legs_;
}
void save()
{
text_oarchive oa{ss};
animal a{4};
oa << a;
}
void load()
{
text_iarchive ia{ss};
animal a;
ia >> a;
std::cout << a.legs() << '\n';
}
int main()
{
save();
load();
}
為了序列化不能修改的類型,可以定義獨立函數(shù) serialize(),如示例 64.5 所示。此函數(shù)需要對相應類型的對象的引用作為其第二個參數(shù)。
將 serialize() 作為獨立函數(shù)實現(xiàn)需要可以從外部訪問類的基本成員變量。在示例 64.5 中,serialize() 只能作為獨立函數(shù)實現(xiàn),因為 legs_ 不再是動物類的私有成員變量。
Boost.Serialization 為標準庫中的許多類提供了 serialize() 函數(shù)。要序列化基于標準類的對象,需要包含額外的頭文件。
示例 64.6。序列化字符串
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
using namespace boost::archive;
std::stringstream ss;
class animal
{
public:
animal() = default;
animal(int legs, std::string name) :
legs_{legs}, name_{std::move(name)} {}
int legs() const { return legs_; }
const std::string &name() const { return name_; }
private:
friend class boost::serialization::access;
template <typename Archive>
friend void serialize(Archive &ar, animal &a, const unsigned int version);
int legs_;
std::string name_;
};
template <typename Archive>
void serialize(Archive &ar, animal &a, const unsigned int version)
{
ar & a.legs_;
ar & a.name_;
}
void save()
{
text_oarchive oa{ss};
animal a{4, "cat"};
oa << a;
}
void load()
{
text_iarchive ia{ss};
animal a;
ia >> a;
std::cout << a.legs() << '\n';
std::cout << a.name() << '\n';
}
int main()
{
save();
load();
}
Example?64.6
示例 64.6 通過添加 name_ 擴展類 animal,這是一個 std::string 類型的成員變量。為了序列化此成員變量,必須包含頭文件 boost/serialization/string.hpp 以提供適當?shù)莫毩⒑瘮?shù) serialize()。
如前所述,Boost.Serialization 為標準庫中的許多類定義了 serialize() 函數(shù)。這些函數(shù)在頭文件中定義,這些頭文件的名稱與標準中相應的頭文件相同。因此,要序列化 ??std::string 類型的對象,請包含頭文件 boost/serialization/string.hpp,要序列化 ??std::vector 類型的對象,請包含頭文件 boost/serialization/vector.hpp。要包含哪個頭文件是相當明顯的。
到目前為止被忽略的 serialize() 的一個參數(shù)是版本。此參數(shù)有助于使存檔向后兼容。示例 64.7 可以加載由示例 64.5 創(chuàng)建的存檔。示例 64.5 中動物類的版本不包含名稱。示例 64.7 在加載存檔時檢查版本號,并且僅在版本大于 0 時才訪問名稱。這允許它處理創(chuàng)建時沒有名稱的舊存檔。
示例 64.7。與版本號的向后兼容性
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
using namespace boost::archive;
std::stringstream ss;
class animal
{
public:
animal() = default;
animal(int legs, std::string name) :
legs_{legs}, name_{std::move(name)} {}
int legs() const { return legs_; }
const std::string &name() const { return name_; }
private:
friend class boost::serialization::access;
template <typename Archive>
friend void serialize(Archive &ar, animal &a, const unsigned int version);
int legs_;
std::string name_;
};
template <typename Archive>
void serialize(Archive &ar, animal &a, const unsigned int version)
{
ar & a.legs_;
if (version > 0)
ar & a.name_;
}
BOOST_CLASS_VERSION(animal, 1)
void save()
{
text_oarchive oa{ss};
animal a{4, "cat"};
oa << a;
}
void load()
{
text_iarchive ia{ss};
animal a;
ia >> a;
std::cout << a.legs() << '\n';
std::cout << a.name() << '\n';
}
int main()
{
save();
load();
}
宏 BOOST_CLASS_VERSION 為類分配版本號。示例 64.7 中類動物的版本號為 1。如果未使用 BOOST_CLASS_VERSION,版本號默認為 0。
版本號存儲在存檔中并且是其中的一部分。雖然在序列化期間使用通過 BOOST_CLASS_VERSION 宏為特定類指定的版本號,但在恢復時將 serialize() 的參數(shù)版本設(shè)置為存儲在存檔中的值。如果新版本的 animal 訪問包含用舊版本序列化的對象的存檔,則成員變量 name_ 不會被恢復,因為舊版本沒有這樣的成員變量。
- 練習
創(chuàng)建一個程序,將 std::runtime_error 類型的對象序列化為一個文件并再次加載它。
原文鏈接:https://yamagota.blog.csdn.net/article/details/128060954
相關(guān)推薦
- 2022-12-23 go語言優(yōu)雅地處理error工具及技巧詳解_Golang
- 2022-06-16 golang?gorm更新日志執(zhí)行SQL示例詳解_Golang
- 2022-12-01 解決k8s?namespace?一直處于?Terminating?狀態(tài)的問題_云其它
- 2022-05-01 C#中的三種定時計時器Timer用法介紹_C#教程
- 2022-08-24 K8S之StatefulSet有狀態(tài)服務詳解_云其它
- 2022-12-15 QT中對話框的使用示例詳解_C 語言
- 2022-08-23 python使用redis模塊來跟redis實現(xiàn)交互_python
- 2022-08-04 C#中ListView用法實例_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支