將物件在記憶體中的狀態轉換為可儲存、可傳輸的位元組流(或文本流)的過程。逆過程為反序列化。核心用途:
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| Google Protobuf | 極高效能、跨語言(C++/Java/Python)、體積小、向前/向後相容 | 需預定義 .proto 再編譯、不支援 STL 容器、不支援二維陣列/指標 | 高效能內部 RPC、跨語言服務、資料定義穩定 |
| Boost.Serialization | 非侵入式、完美支援 STL/智慧指標/多態、多種格式(二進制/XML/文本)、純 C++ 模板實現 | 編譯慢、庫巨大(安裝繁瑣)、基本型別指標難序列化、不支援變長陣列 | 複雜 C++ 物件圖持久化、需 STL 容器、不想改動既有類別 |
| MFC Serialization | Visual Studio 整合好、CObject 體系原生支援 | 僅限 Windows、效率低、綁定 MFC | 舊 MFC 專案維護 |
| .NET Framework | 跨語言(CLR)、自動處理版本、支援完整物件圖 | 需 .NET Runtime、非標準 C++ | .NET 生態內部 |
| .proto 型別 | C++ 型別 | 備註 |
|---|---|---|
| int32 / int64 | int32 / int64 | 負數編碼低效,建議用 sint32/64 |
| uint32 / uint64 | uint32 / uint64 | Varint 編碼 |
| sint32 / sint64 | int32 / int64 | ZigZag 編碼,負數高效 |
| fixed32 / fixed64 | uint32 / uint64 | 固定 4/8 字節,大數值更高效 |
| sfixed32 / sfixed64 | int32 / int64 | 固定長度有符號 |
| bool | bool | |
| string | std::string | UTF-8 或 7-bit ASCII |
| bytes | std::string | 任意位元組序列 |
vector<vector<int>>、map、set 等。需手動展平或用 repeated 模擬一維陣列。message A { message B {} } 生成的類為 A_B 而非 B。解決:將巢狀類提到頂層定義。# 必裝依賴
sudo apt-get install libbz2-dev zlib1g-dev libpython3-dev
# 源碼安裝
./bootstrap.sh
./b2 -j$(nproc) --with-serialization --with-system --with-filesystem
sudo ./b2 install
常見錯誤:
pyconfig.h not found → 裝 python3-dev。bzlib.h not found → 裝 libbz2-dev。-lboost_serialization:窄字符(char)。-lboost_wserialization:寬字符(wchar_t)。類別成員必須 public,或在類內聲明:
class MyClass {
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, unsigned version) {
ar & member1 & member2;
}
private:
int member1; string member2;
};
int*)無法直接序列化:需包裝成結構體。new T[n] 不能直接序列化:需用 std::vector 或固定大小陣列 T arr[N]。new A[n] 會被當成單一物件:只序列化第一個元素。必須用 A arr[N] 或 vector<A>。需要跨語言 / 極致效能 / 結構固定? → Protobuf
需要 STL 容器 / 複雜物件圖 / 不想改既有代碼 / 純 C++? → Boost.Serialization
Windows 老專案 / MFC 體系? → MFC
.NET 生態? → .NET BinaryFormatter / JSON.NET
Protobuf 輕量、快、跨語言,適合「定義一次,到處用」的服務介面。Boost.Serialization 重裝備、功能全、非侵入,適合「既有複雜 C++ 物件模型持久化」的場景。兩者互補,而非替代。根據專案實際約束選擇,切勿盲目跟風。