Boost程式庫完全開發指南——深入C++“準”標準庫(第2版)

Boost程式庫完全開發指南——深入C++“準”標準庫(第2版)

1024.1.2 1024.1.3 1214.5.1

基本資料

Boost程式庫完全開發指南——深入C++“標準庫(第2版)
羅劍鋒著.
ISBN 978-7-121-19089-6
20131月出版
定價:99.00
600
16

內容提要

Boost是一個功能強大、構造精巧、跨平台、開源並且完全免費的C++程式庫,有著“C++‘準’標準庫”的美譽。
Boost由C++標準委員會部分成員所設立的Boost社區開發並維護,使用了許多現代C++編程技術,內容涵蓋字元串處理、正則表達式、容器與數據結構、並發編程、函式式編程、泛型編程、設計模式實現等許多領域,極大地豐富了C++的功能和表現力,能夠使C++軟體開發更加簡捷、優雅、靈活和高效。
本書基於2012年8月發布的Boost1.51版,介紹了其中的所有117個庫,並且結合C++11標準詳細、深入地講解了其中數十個庫,同時實現了若干頗具實用價值的工具類和函式,可幫助讀者迅速地理解、掌握Boost的用法及其在實際開發工作中的套用。
本書內容豐富、結構嚴謹、詳略得當、講解透徹,帶領讀者領略了C++的最新前沿技術,相信會是每位C++程式設計師的必備工具書。

書本目錄

第0章 導讀

0.1 關於本書 1
0.2 讀者對象 1
0.3 本書的術語與風格 2
0.4 本書的結構 3
0.5 如何閱讀本書 5

第1章 Boost程式庫總論

1.1 關於Boost 7
1.1.1 什麼是Boost 7
1.1.2 安裝Boost 8
1.1.3 使用Boost 8
1.2 關於STLport 9
1.2.1 什麼是STLport 9
1.2.2 安裝STLport 10
1.2.3 編譯STLport 10
1.2.4 使用STLport 10
1.3 開發環境簡介 11
1.4 開發環境搭建 12
1.4.1 UNIX開發環境 12
1.4.2 Windows開發環境 13
1.4.3 高級議題 14
1.5 總結 16

第2章 時間與日期

2.1 timer庫概述17
2.2 timer 18
2.2.1 用法 18
2.2.2 類摘要 19
2.2.3 使用建議 20
2.3 progress_timer 20
2.3.1 用法 20
2.3.2 類摘要 21
2.3.3 擴展計時精度 22
2.4 progress_display 24
2.4.1 類摘要 24
2.4.2 用法 25
2.4.3 注意事項 26
2.5 date_time庫概述27
2.5.1 編譯date_time庫 28
2.5.2 date_time庫的基本概念 29
2.6 處理日期 29
2.6.1 日期 30
2.6.2 創建日期對象 30
2.6.3 訪問日期 32
2.6.4 日期的輸出 33
2.6.5 與tm結構的轉換 34
2.6.6 日期長度 34
2.6.7 日期運算 35
2.6.8 日期區間 37
2.6.9 日期區間運算 38
2.6.10 日期疊代器 40
2.6.11 其他功能 41
2.6.12 綜合運用 41
2.7 處理時間 44
2.7.1 時間長度 44
2.7.2 操作時間長度 45
2.7.3 時間長度的精確度 47
2.7.4 時間點 48
2.7.5 創建時間點對象 49
2.7.6 操作時間點對象 50
2.7.7 與tm、time_t等結構
的轉換 51
2.7.8 時間區間 51
2.7.9 時間疊代器 52
2.7.10 綜合運用 52
2.8 date_time庫的高級議題 56
2.8.1 編譯配置宏 56
2.8.2 格式化時間 56
2.8.3 本地時間 57
2.8.4 序列化 59
2.9 總結 59

第3章 記憶體管理

3.1 smart_ptr庫概述 61
3.1.1 RAII機制 61
3.1.2 智慧型指針 62
3.2 scoped_ptr 63
3.2.1 類摘要 63
3.2.2 操作函式 64
3.2.3 用法 65
3.2.4 與auto_ptr的區別 66
3.2.5 與unique_ptr的區別 67
3.3 scoped_array69
3.3.1 類摘要 69
3.3.2 用法 69
3.3.3 與unique_ptr的區別 70
3.3.4 使用建議 71
3.4 shared_ptr 72
3.4.1 類摘要 72
3.4.2 操作函式 73
3.4.3 用法 75
3.4.4 工廠函式 76
3.4.5 套用於標準容器 77
3.4.6 套用於橋接模式 79
3.4.7 套用於工廠模式 80
3.4.8 定製刪除器 81
3.4.9 高級議題 83
3.5 shared_array84
3.5.1 類摘要 84
3.5.2 用法 84
3.6 weak_ptr 85
3.6.1 類摘要 85
3.6.2 用法 86
3.6.3 獲得this的shared_ptr 87
3.6.4 打破循環引用 88
3.7 intrusive_ptr 89
3.8 pool庫概述 89
3.9 pool 90
3.9.1 類摘要 90
3.9.2 操作函式 91
3.9.3 用法 91
3.10 object_pool 92
3.10.1 類摘要 92
3.10.2 操作函式 93
3.10.3 用法 93
3.10.4 使用更多的構造參數 94
3.11 singleton_pool 95
3.11.1 類摘要 96
3.11.2 用法 96
3.12 pool_alloc 97
3.13 總結 98

第4章 實用工具

4.1 noncopyable 101
4.1.1 原理 102
4.1.2 用法 102
4.1.3 原理 103
4.2 typeof 104
4.2.1 動機 104
4.2.2 用法 106
4.2.3 向typeof庫註冊自定義類 107
4.2.4 使用建議 108
4.3 optional 108
4.3.1 “無意義”的值 108
4.3.2 類摘要 109
4.3.3 操作函式 109
4.3.4 用法 110
4.3.5 工廠函式 111
4.3.6 高級議題 112
4.4 assign 113
4.4.1 使用操作符+=向容器
增加元素 113
4.4.2 使用操作符()向容器
增加元素 114
4.4.3 初始化容器元素 115
4.4.4 減少重複輸入 117
4.4.5 搭配非標準容器工作 118
4.4.6 高級用法 120
4.5 swap 121
4.5.1 原理 121
4.5.2 交換數組 122
4.5.3 特化std::swap 122
4.5.4 特化ADL可找到的swap 123
4.5.5 使用建議 124
4.6 singleton 124
4.6.1 boost.pool的單件實現 125
4.6.2 boost.serialzation的
單件實現 127
4.7 tribool 129
4.7.1 類摘要 129
4.7.2 用法 130
4.7.3 為第三態更名 131
4.7.4 輸入/輸出 132
4.7.5 與optional<bool>的區別 132
4.8 operators 133
4.8.1 基本運算概念 134
4.8.2 算術操作符的用法 135
4.8.3 基類鏈 137
4.8.4 複合運算概念 138
4.8.5 相等與等價 140
4.8.6 解引用操作符 141
4.8.7 下標操作符 142
4.8.8 高級議題 143
4.9 exception 144
4.9.1 標準庫中的異常 145
4.9.2 類摘要 146
4.9.3 向異常傳遞信息 147
4.9.4 更進一步的用法 148
4.9.5 包裝標準異常 150
4.9.6 使用函式拋出異常 151
4.9.7 獲得更多的調試信息 152
4.9.8 高級議題 153
4.10 uuid 155
4.10.1 類摘要 155
4.10.2 用法 156
4.10.3 生成器 158
4.10.4 增強的uuid類160
4.10.5 與字元串的轉換 161
4.10.6 SHA1摘要算法 162
4.11 config 163
4.11.1 BOOST_STRINGIZE 163
4.11.2 BOOST_STATIC_
CONSTANT 164
4.11.3 其他工具 165
4.12 utility 165
4.12.1 BOOST_BINARY 165
4.12.2 BOOST_CURRENT_
FUNCTION 166
4.13 總結 167

第5章 字元串與文本處理

5.1 lexical_cast 171
5.1.1 用法 172
5.1.2 異常bad_lexical_cast 173
5.1.3 對轉換對象的要求 174
5.1.4 套用於自己的類 174
5.2 format 175
5.2.1 簡單的例子 176
5.2.2 輸入操作符% 177
5.2.3 類摘要 179
5.2.4 格式化語法 180
5.2.5 format的性能 181
5.2.6 高級用法 181
5.3 string_algo 182
5.3.1 簡單的例子 183
5.3.2 string_algo概述184
5.3.3 大小寫轉換 185
5.3.4 判斷式(算法) 185
5.3.5 判斷式(函式對象) 187
5.3.6 分類 188
5.3.7 修剪 189
5.3.8 查找 190
5.3.9 替換與刪除 191
5.3.10 分割 193
5.3.11 合併 195
5.3.12 查找(分割)疊代器 196
5.4 tokenizer 197
5.4.1 類摘要 197
5.4.2 用法 198
5.4.3 分詞函式對象 199
5.4.4 char_separator 199
5.4.5 escaped_list_separator 201
5.4.6 offset_separator 201
5.4.7 tokenizer庫的缺陷 202
5.5 xpressive 204
5.5.1 兩種使用方式 204
5.5.2 正則表達式語法簡介 205
5.5.3 類摘要 206
5.5.4 匹配 208
5.5.5 查找 211
5.5.6 替換 212
5.5.7 疊代 213
5.5.8 分詞 215
5.5.9 與regex的區別216
5.5.10 高級議題 217
5.6 總結 219

第6章 正確性與測試

6.1 assert 221
6.1.1 基本用法 221
6.1.2 禁用斷言 222
6.1.3 擴展用法 223
6.1.4 BOOST_ASSERT_MSG224
6.1.5 BOOST_VERIFY 225
6.2 static_assert 225
6.2.1 定義 226
6.2.2 用法 226
6.2.3 使用建議 228
6.3 test 228
6.3.1 編譯test庫 228
6.3.2 最小化的測試套件 229
6.3.3 單元測試框架簡介 231
6.3.4 測試斷言 231
6.3.5 測試用例與套件 232
6.3.6 測試實例 234
6.3.7 測試夾具 235
6.3.8 測試日誌 237
6.3.9 運行參數 238
6.3.10 函式執行監視器 239
6.3.11 程式執行監視器 242
6.3.12 高級議題 242
6.4 總結 245

第7章 容器與數據結構

7.1 array 247
7.1.1 類摘要 248
7.1.2 操作函式 248
7.1.3 用法 249
7.1.4 能力限制 250
7.1.5 初始化 251
7.1.6 零長度的數組 251
7.1.7 與C++11標準的區別 252
7.1.8 實現ref_array 252
7.1.9 ref_array的用法 254
7.2 dynamic_bitset 254
7.2.1 類摘要 255
7.2.2 創建與賦值 256
7.2.3 容器操作 257
7.2.4 位運算與比較運算 258
7.2.5 訪問元素 259
7.2.6 類型轉換 260
7.2.7 集合操作 261
7.2.8 綜合運用 261
7.3 unordered 263
7.3.1 散列集合簡介 263
7.3.2 散列集合的用法 265
7.3.3 散列映射簡介 267
7.3.4 散列映射的用法 269
7.3.5 高級議題 271
7.4 bimap 272
7.4.1 類摘要 273
7.4.2 基本用法 273
7.4.3 值的集合類型 275
7.4.4 集合類型的用法 276
7.4.5 使用標籤類型 277
7.4.6 使用assign庫 279
7.4.7 查找與替換 279
7.4.8 投射 281
7.4.9 高級議題 282
7.5 circular_buffer 283
7.5.1 類摘要 283
7.5.2 用法 284
7.5.3 環形緩衝區 285
7.5.4 空間最佳化型緩衝區 286
7.6 tuple 287
7.6.1 最簡單的tuple:pair 287
7.6.2 類摘要 288
7.6.3 創建與賦值 288
7.6.4 訪問元素 290
7.6.5 比較操作 291
7.6.6 輸入輸出 292
7.6.7 連結變數 293
7.6.8 套用於assign庫 293
7.6.9 套用於exception庫 294
7.6.10 內部結構 294
7.6.11 使用訪問者模式 295
7.6.12 高級議題 297
7.7 any299
7.7.1 類摘要 299
7.7.2 訪問元素 300
7.7.3 用法 301
7.7.4 簡化的操作函式 302
7.7.5 保存指針 303
7.7.6 輸出 304
7.7.7 套用於容器 306
7.8 variant 306
7.8.1 類摘要 307
7.8.2 訪問元素 308
7.8.3 用法 308
7.8.4 訪問器 309
7.8.5 與any的區別 312
7.8.6 高級議題 312
7.9 multi_array 314
7.9.1 類摘要 314
7.9.2 用法 316
7.9.3 多維數組生成器 318
7.9.4 改變形狀和大小 319
7.9.5 創建子視圖 320
7.9.6 適配普通數組 322
7.9.7 高級議題 323
7.10 property_tree 326
7.10.1 類摘要 327
7.10.2 讀取配置信息 328
7.10.3 寫入配置信息 330
7.10.4 更多用法 331
7.10.5 XML數據格式 332
7.10.6 其他數據格式 333
7.10.7 高級議題 335
7.11 總結 336

第8章 算法

8.1 foreach 339
8.1.1 用法 340
8.1.2 詳細解說 341
8.1.3 更優雅的名字 342
8.1.4 支持的序列類型 343
8.1.5 一個小問題 344
8.2 minmax 345
8.2.1 用法 345
8.2.2 使用tuples::tie 346
8.3 minmax_element 347
8.3.1 用法 347
8.3.2 其他函式的用法 348
8.4 總結 349

第9章 數學與數字

9.1 integer 351
9.1.1 integer_traits 351
9.1.2 標準整數類型 353
9.1.3 整數類型模板類 355
9.2 rational 358
9.2.1 類摘要 358
9.2.2 創建與賦值 359
9.2.3 算術運算與比較運算 360
9.2.4 類型轉換 360
9.2.5 輸入輸出 361
9.2.6 分子與分母 361
9.2.7 與數學函式配合工作 361
9.2.8 異常 361
9.2.9 rational的精度 362
9.2.10 實現無限精度的
整數類型 362
9.2.11 最大公約數和最小
公倍數 367
9.3 crc 367
9.3.1 類摘要 368
9.3.2 預定義的實現類 368
9.3.3 計算CRC 369
9.3.4 CRC函式 370
9.3.5 自定義CRC函式 371
9.4 random 371
9.4.1 偽隨機數發生器 372
9.4.2 偽隨機數發生器的構造 373
9.4.3 偽隨機數發生器的拷貝 374
9.4.4 隨機數分布器 375
9.4.5 隨機數分布器類摘要 376
9.4.6 隨機數分布器用法 379
9.4.7 變數發生器 379
9.4.8 產生隨機數據塊 381
9.4.9 真隨機數發生器 382
9.4.10 實現真隨機數發生器 383
9.5 總結 384

第10章 作業系統相關

10.1 io_state_savers 387
10.1.1 類摘要 388
10.1.2 用法 388
10.1.3 簡化new_progress_timer 390
10.2 system390
10.2.1 編譯system庫 391
10.2.2 錯誤值枚舉 391
10.2.3 錯誤類別 392
10.2.4 錯誤代碼 393
10.2.5 錯誤異常 395
10.3 cpu_timer 396
10.3.1 編譯cpu_timer庫 396
10.3.2 時間類型 397
10.3.3 cpu_timer398
10.3.4 auto_cpu_timer 400
10.3.5 定製輸出格式 401
10.4 filesystem 402
10.4.1 編譯filesystem庫 402
10.4.2 類摘要 403
10.4.3 路徑表示 405
10.4.4 可移植的檔案名稱 406
10.4.5 路徑處理 407
10.4.6 異常 409
10.4.7 檔案狀態 410
10.4.8 檔案屬性 412
10.4.9 檔案操作 413
10.4.10 疊代目錄 414
10.4.11 實例1:實現查找
檔案功能 417
10.4.12 實例2:實現模糊查找
檔案功能 418
10.4.13 實例3:實現拷貝
目錄功能 420
10.4.14 檔案流操作 422
10.5 program_options422
10.5.1 編譯program_options庫 423
10.5.2 概述 424
10.5.3 選項值 426
10.5.4 選項描述器 427
10.5.5 選項描述器的用法 428
10.5.6 分析器 430
10.5.7 存儲器 432
10.5.8 使用位置選項值 432
10.5.9 分析環境變數 434
10.5.10 分組選項信息 435
10.5.11 高級用法 437
10.6 總結 440

第11章 函式與回調

11.1 result_of 443
11.1.1 原理 444
11.1.2 用法 444
11.2 ref 446
11.2.1 類摘要 447
11.2.2 基本用法 447
11.2.3 工廠函式 448
11.2.4 操作包裝 449
11.2.5 綜合套用 450
11.2.6 為ref增加函式調用功能 451
11.3 bind 453
11.3.1 工作原理 453
11.3.2 綁定普通函式 454
11.3.3 綁定成員函式 455
11.3.4 綁定成員變數 457
11.3.5 綁定函式對象 457
11.3.6 使用ref庫 458
11.3.7 高級議題 459
11.4 function 461
11.4.1 類摘要 462
11.4.2 function的聲明 462
11.4.3 操作函式 463
11.4.4 比較操作 464
11.4.5 用法 464
11.4.6 使用ref庫 465
11.4.7 用於回調 467
11.4.8 與typeof的區別 469
11.5 signals2 469
11.5.1 類摘要 470
11.5.2 操作函式 471
11.5.3 插槽的連線與調用 472
11.5.4 信號的返回值 474
11.5.5 合併器 474
11.5.6 管理信號的連線 476
11.5.7 更靈活的管理信號連線 477
11.5.8 自動連線管理 480
11.5.9 套用於觀察者模式 482
11.5.10 高級議題 485
11.6 總結 489

第12章 並發編程

12.1 thread 491
12.1.1 編譯thread庫492
12.1.2 時間功能 493
12.1.3 互斥量 493
12.1.4 執行緒對象 496
12.1.5 創建執行緒 497
12.1.6 操作執行緒 499
12.1.7 中斷執行緒 500
12.1.8 執行緒組 504
12.1.9 條件變數 505
12.1.10 共享互斥量 508
12.1.11 future 510
12.1.12 高級議題 513
12.2 asio 518
12.2.1 概述 519
12.2.2 定時器 520
12.2.3 定時器用法 521
12.2.4 網路通信簡述 524
12.2.5 IP位址和端點 525
12.2.6 同步socket處理 526
12.2.7 異步socket處理 528
12.2.8 查詢網路地址 532
12.2.9 高級議題 533
12.3 總結 537

第13章 程式語言支持

13.1 python庫概述 539
13.1.1 Python語言簡介 540
13.1.2 安裝Python環境 541
13.1.3 編譯python庫541
13.1.4 使用python庫542
13.2 嵌入Python543
13.2.1 初始化解釋器 543
13.2.2 封裝Python對象 544
13.2.3 執行Python語句 546
13.2.4 異常處理 547
13.3 擴展Python548
13.3.1 最簡單的例子 549
13.3.2 導出函式 551
13.3.3 導出重載函式 552
13.3.4 導出類 554
13.3.5 導出類的更多細節 556
13.3.6 高級議題 558
13.4 總結 560

第14章 其他Boost組件

14.1 算法 563
14.2 字元串和文本處理 564
14.3 容器與數據結構565
14.4 疊代器566
14.5 函式對象與高級編程566
14.6 泛型編程 568
14.7 模板元編程569
14.8 預處理元編程 569
14.9 並發編程 570
14.10 數學與數字 570
14.11 TR1實現 571
14.12 輸入輸出 571
14.13 雜項 572
14.14 總結 574

第15章 Boost與設計模式

15.1 創建型模式575
15.2 結構型模式577
15.3 行為模式 580
15.4 其他模式 583
15.5 總結 584

第16章 結束語

16.1 未臻完美的Boost 587
16.2 讓Boost工作得更好 588
16.3 工夫在詩外590
附錄A 推薦書目593
附錄B C++標準簡述 595
附錄C STL簡述 597

精彩節摘

推薦序
最近一年我電話面試了數十位C++應聘者,慣用的暖場問題是“工作中使用過STL的哪些組件?用過Boost的哪些組件?”得到的答案大多集中在vector、map和shared_ptr。如果對方是在校學生,我一般會問問vector或map的內部實現、各種操作的複雜度,以及疊代器失效的可能場景。如果是有經驗的程式設計師,我還會追問shared_ptr的執行緒安全性、循環引用的後果及如何避免、weak_ptr的作用等。如果這些都回答得不錯,進一步還可以問問如何實現執行緒安全的引用計數,如何定製刪除動作等。這些問題讓我能迅速地判別對方的C++水平。
我之所以在面試時問到Boost,是因為其中的許多組件確實可以用於編寫可維護的產品代碼。Boost包含近百個程式庫,其中不乏具有工程實用價值的佳品。每個人口味與技術背景不一樣,對Boost的取捨也不一樣。就我的個人經驗而言,首先可以使用絕對無害的庫,例如noncopyable、scoped_ptr、static_assert等,這些庫的學習和使用都比較簡單,容易入手。其次,有些功能自己實現起來並不困難,正好Boost里提供了現成的代碼,那就不妨一用,比如date_time和circular_buffer等。然後,在新項目中,對於訊息傳遞和資源管理可以考慮採用更加現代的方式,例如用function/bind在某些情況下代替虛函式作為庫的回調接口、藉助shared_ptr實現執行緒安全的對象回調等。這二者會影響整個程式的設計思路與風格,需要通盤考慮,如果正確使用智慧型指針,在現代C++程式里一般不需要出現delete語句。最後,對某些性能不佳的庫保持警惕,比如lexical_cast。總之,在項目組成員人人都能理解並運用的基礎上,適當引入現成的Boost組件,以減少重複勞動,提高生產力。
Boost是一個寶庫,其中既有可以直接拿來用的代碼,也有值得借鑑的設計思路。試舉一例:正則表達式庫regex對執行緒安全的處理。
早期的RegEx類不是執行緒安全的,它把“正則表達式”和“匹配動作”放到了一個類裡邊。由於有可變數據,RegEx的對象不能跨執行緒使用。如今的RegEx明確地區分了不可變(immutable)與可變(mutable)的數據,前者可以安全地跨執行緒共享,後者則不行。比如正則表達式本身(basic_regex)與一次匹配的結果(match_results)是不可變的;而匹配動作本身(match_regex)涉及狀態更新,是可變的,於是用可重入的函式將其封裝起來,不讓這些數據泄露給別的執行緒。正是由於做了這樣合理的區分,RegEx在正常使用時就不必加鎖。
Donald Knuth 在“Coders at Work”一書里表達了這樣一個觀點:如果程式設計師的工作就是擺弄參數去調用現成的庫,而不知道這些庫是如何實現的,那么這份職業就沒啥樂趣可言。換句話說,固然我們強調工作中不要重新發明輪子,但是作為一個合格的程式設計師,應該具備自製輪子的能力。非不能也,是不為也。
C/C++語言的一大特點是其標準庫可以用語言自身實現。C標準庫的strlen、strcpy、strcmp系列函式是教學與練習的好題材,C++標準庫的complex、string、vector則是類、資源管理、模板編程的絕佳示範。在深入了解STL的實現之後,運用STL自然手到擒來,並能自動避免一些錯誤和低效的用法。
對於Boost也是如此,為了消除使用時的疑慮,為了用得更順手,有時我們需要適當了解其內部實現,甚至編寫簡化版用做對比驗證。但是由於Boost代碼用到了日常應用程式開發中不常見的高級語法和技巧,並且為了跨多個平台和編譯器而大量使用了預處理宏,閱讀 Boost源碼並不輕鬆愜意,需要下一番功夫。另一方面,如果沉迷於這些有趣的底層細節而忘了原本要解決什麼問題,恐怕就捨本逐末了。
Boost中的很多庫是按泛型編程的範式來設計的,對於熟悉面向對象編程的人而言,或許面臨一個思路的轉變。比如,你得熟悉泛型編程的那套術語,如concept、model、refinement,才容易讀懂Boost.Threads文檔中關於各種鎖的描述。我想,對於熟悉STL設計理念的人而言,這不是什麼大問題。
在某些領域,Boost不是唯一的選擇,也不一定是最好的選擇。比如,要生成公式化的原始碼,我會首選用腳本語言寫一小段代碼生成程式,而不用Boost.Preprocessor;要在C++程式中嵌入領域特定語言,我會首選用Lua或其他語言解釋器,而不用Boost.Proto;要用C++程式解析上下文無關文法,我會首選用ANTLR來定義詞法與語法規則並生成解析器(parser),而不用Boost.Spirit。總之,使用Boost時心態要平和,別較勁去改造C++語言。把它有助於提高生產力的那部分功能充分發揮出來,讓項目從中受益才是關鍵。
要學習Boost,除了閱讀其官方網站的文檔、示例與源碼之外,最好能有一本比較全面的中文書在手邊隨時翻閱。對於不諳英文的開發者,這更是可幸之至。您手上這本《Boost 程式庫完全開發指南》是很好的使用指南與參考手冊。作者由淺入深地介紹了Boost的大部分常用內容,能讓讀者迅速了解Boost,並從中找到自己需要的部分。拿到這本書稿之後,我有粗有細地閱讀了一遍,總體來看,作者水平很高,也相當務實,對C++和Boost的理解與運用很到位,我從這本書學到了不少新知識。為此,我樂於向希望學習Boost程式庫的開發者推薦這本靠譜的書。
須知“功不唐捐”,作為一名現代C++程式設計師,在Boost上投入的精力定能獲得回報。
陳碩
《代碼大全》譯者之一
中國·香港

第1版前言

屈指算來,接觸C++語言至今已經有十餘個年頭了。回首往事,不禁感慨良多。

緣起

1996年我上大學最開始學的是Pascal,不得不說,Pascal嚴謹的程式風格確實很適合作為一門教學語言,然而用於實際開發就不那么合適了(直到出現Delphi)。由於當時學校並未開設C語言課程,因此在Pascal課程結束後我就買書自學C/C++語言,並在次年報名計算機軟體專業技術資格和水平考試,靠著一點點編程和考試的“天分”獲得了高級程式設計師資質(當年很熱衷考級考證,後來就“淡定”多了)。雖然有了資格證,但我仍然算是個C++的初學者,對於C++的認識還處於C的面向過程和簡單的基於對象層次上。
新千年伊始我考入了北京理工大學就讀研究生,因為跟導師做項目開始接觸STL與C++標準庫,大概是2005年從1.33版結識了Boost,這才真正領略了C++的精髓。那段時期Java和C#正在國內大行其道,C++則勢單力薄,有關STL和C++標準的技術書籍寥寥無幾,而講解Boost的書更是為零,故對Boost的學習基本只能靠自己的摸索與實踐。好在Boost自帶的文檔相當豐富(儘管看全英文的資料十分辛苦),而且源碼也寫得比較清晰規範,在熟悉了STL的基礎上學習Boost倒也並不算太難。
但Boost的一個最大的特點就是“龐大”,功能組件眾多,要想把它全部裝進腦子裡融會貫通基本上是不可能的,使用時需要經常查閱英文文檔,相當麻煩。因此,在學習的過程中,我逐漸產生了編寫學習筆記的想法。一開始只是一個簡單的純文本檔案,記錄了一些使用經驗的片斷,隨著積累不斷增加,純文本形式已經不能夠滿足知識整理的需求了,於是我又把這些文字遷移到了Word文檔里,把使用經驗分類編目,進行較系統的歸納梳理。慢慢地,這份學習筆記居然有了上萬字的規模,成為了一份很好的Boost備忘參考,在日常的開發工作中給了我很大的幫助——就像《設計模式》一書中所說的那樣,捕獲了很多使用Boost解決問題的實踐經驗,避免了重複發現。不過,這份資料一直僅限於我個人使用,屬於“自娛自樂”的作品,從未示人。
時間一晃到了2010年1月份的某天夜裡,不知道是什麼原因我忽然失眠了,躺在床上翻來覆去怎么也睡不著。突然,一個念頭闖入了腦海:把Boost開發經驗整理出版吧,讓更多人能夠分享這些知識,正所謂“獨樂樂,與眾樂樂,孰樂?”這個大膽的想法的出現讓我那天的失眠又延長了幾個小時——關於書的各種構想在頭腦中“肆虐橫行”。
隨後的幾天裡我就把這個想法付諸行動了,雖然以前也寫過並發表很多文章,也在網上印刷了幾本個人文集,但出版正式的書還是第一次。在把學習筆記進一步整理完善,編寫出較完整的結構和一個樣章後,我就開始聯繫出版社了。當初並沒有多大的信心,畢竟我這個作者名不見經傳,也沒有什麼資歷、背景和名氣(而且還是個“網盲”,從未跟隨潮流開個人部落格)。很幸運,發出的第一個E-mail就是電子工業出版社,而且編輯也在第一時間回復了我,這才給了我以持續寫作完成全書的動力。
寫作過程中我也進一步加深了對Boost的認識,澄清了許多原來未曾注意到的細節。原本只打算寫20萬字左右、三百多頁,但寫到中途才發現Boost庫的博大精深遠非當初的理解,也意識到了自己當初學習的膚淺。歷經了近半年近乎不眠不休的努力,最終呈現給讀者的是這本厚達500多頁的圖書,文字量是最初學習筆記的數十倍,內容也翔實豐滿了很多——達成這個結果,我個人可以說是問心無愧了。

C++與Boost

C++較Java和C#等語言的一個最大不同在於它並非是由某個公司或個人把持的,它的真正發展動力來自於廣大程式設計師。Boost就是這樣的一個典範,它成功地填補了從C++98到C++0X這“失落的十年”間的空白,在競爭對手Java和C#不斷更新版本新增特性的時候以庫的形式極大地增強了C++的能力,使C++不至於因為標準規範的滯後而落後於時代,而且Boost還深層次地挖掘了C++的潛力,開創了泛型編程、模板元編程、函式式編程等嶄新的境界。
就個人來說,我比較喜歡的Boost版本有兩個,分別是1.35和1.39。1.35版增加了asio、bimap、circular_buffer等許多重要組件,而1.39版則增加了signals2庫,這兩個版本都在我的工作用機上停留了相當長的時間。落筆之時,Boost已經更新到了1.43版,成長為一個相當完善、全面、強大的C++程式庫。可以毫不誇張地說,現在的C++程式設計師,如果不熟悉Boost,那么至少喪失了一半使用C++的好處,同時會多耗費數倍的開發精力和時間。
隨著C++0X標準的即將來臨,Boost程式庫的發展也出現了加速的趨勢,由原來間隔數月不定期更新版本,改為定期(每3個月左右)發布新版本,而且每個新版本都會包含大量極有價值的更新內容。因此,希望讀者在閱讀本書時及時訪問Boost的官網以便獲取最新的版本。
感謝讀者選擇本書,再說一句真心的“套話”(笑):限於作者水平有限,書中錯漏在所難免,敬請讀者原諒、指正。

致謝

首先我要感謝整個C++群體,特別是:C++語言的發明者Bjarne Stroustrup博士——他給我們帶來了美妙的C++;然後是Alexander Stepanov和C++標準委員會——他們把STL引入了C++,開創了C++的現代編程風格;以及Beman G. Dawes、Boost程式庫的所有作者和Boost社區——他們為我們奉獻了如此高水準的程式庫。
其次我要感謝電子工業出版社博文視點公司,他們給了我這個把自己的開發經驗出版成書的機會,在把潦草的個人學習筆記變成正式圖書的過程中他們付出了艱辛的努力。還要感謝陳碩先生,他審閱了本書的部分手稿,提出了很多有價值的參考意見,並慨然為本書撰寫序言。
接下來我要感謝我的家人:感謝我的父母和弟弟,他們永遠是我生命中最重要的人;感謝我的妻子,她自始至終都支持我的寫作,並擔負了大部分照顧孩子的家務(雖然偶有怨言);還要對已滿一歲半的女兒說聲抱歉,為了寫作本書,我已經犧牲了很多陪她玩耍的時間。
我還要感謝黃美華、馮薇、戚天龍、羅玉震、顏靜、陳剛、張秋香、繆澤波等同事,長期的共事令我們建立了深厚的友誼。對後兩位同事致以特別的感謝,他們對完成本書提供了大力的支持和幫助。
最後,感謝多年以來的好友岳大海、時吉斌、王峰,感謝我的中學老師鄧英、杜愛芹、練鑫雲、陳靜,感謝我的研究生導師賈雲得,以及所有在我成長過程中曾經給予我關心和幫助的朋友們!
羅劍鋒
2010年6月7日於北京王府井

前言

本書第1版面世至今忽忽然不覺已經兩年有餘,其間多蒙讀者厚愛,褒獎有加,不勝感激,在此聊寫些文字,以志心性。
閒談碎語C++
這兩年里對於C++社區來說最重大的事件莫過於是C++11標準的發布了:歷經十餘年的磨礪,嶄新的C++終於揚刀出鞘,諸多新語言特性和庫的加入令C++舊貌換新顏,從此程式設計師手裡的這把寶刀更是增添了無窮的威力,上天入地屠龍伏虎,不在話下。
最近開源界的一樁新聞也不得不提一下:著名的C/C++編譯器GCC於2012年8月完成了從C實現到C++實現的轉換。雖然這件事比不上C++11發布,但足可以從一個側面證明C++的實力已經得到了開源界的高度認可,今後沒有什麼是C++做不出來的了。
作為C++標準的後備,隨著C++11的正式發布,Boost程式庫現在進入了一個新的歷史時期:一方面依據新標準不斷完善自身,另一方面則秉承傳統繼續開拓C++11未涉及的領域。這兩方面可以從Boost歷次巨細靡遺的更新記錄中看出來——不斷修正既有庫中不符合標準的地方,同時再謹慎地引入新的組件,“小步快跑”地奔向“康莊大道”。
由於Boost程式庫正逐漸向C++11標準靠攏,曾經的“準標準庫”美譽已經不太合適了,它更像是一個比C++標準庫更加“兼容”、更加“標準”的“超級標準庫”——使用Boost可以完全消除C++11和C++98之間的差異,稍微有點誇張地說:學習Boost就相當於學習現代C++,使用現代C++必然避不開Boost。
國內外的許多公司都已經把Boost作為自己源碼資產的一部分,在這些高質量的軟體組件之上開發產品,更激進的如Facebook則是走在了潮流的前面,同時使用最新的C++11和Boost來開發軟體(如開源的folly)。面對新技術,我們應該克服心中的怯懦和懶惰,積極學習,力爭“站在C++98的最高峰沐浴C++11的陽光”。
對第1版的改動
本書第1版撰寫於2010年年初,彼時C++新標準尚未確定,國內了解、使用Boost的人也不多,故書的內容偏重於入門和介紹。而現在的情況則已經大有不同:C++11標準相當於是一個全新的語言,獲得了諸多編譯器生產商的積極回響,移動網際網路的興起也使得國內的程式設計師群體開始越來越多地關心起C++和Boost,整體C++水平有所提升。
鑒於這些變化,第2版在保持原書風格的同時做了適當調整,刪去了一些淺顯的部分,並依據最新的C++11和Boost程式庫全面更新,較第1版略增加深度,但仍然還是以入門為主,不過多介紹庫的實現細節。由於C++11標準有很多新的語言特性和庫,包含了部分Boost庫原有的功能,故作者弱化了一些與C++11語言特性重複的庫,對於庫組件則著重講解符合C++11標準的功能。
慨括
本書第2版幾乎每頁都較前一版有修改,各章的重大變化列舉如下。
? 第1章 重新組織了結構,分別介紹UNIX和Windows開發環境;
? 第3章 增加對unique_ptr的介紹,補充完善對weak_ptr的論述;
? 第4章 typeof庫推薦改用C++11的auto,刪除4.11.3節;
? 第6章 增加對C++11 static_assert關鍵字的介紹;
? 第7章 array、unordered、tuple庫更新為C++11標準;
? 第8章 foreach推薦改用C++11的for,minmax庫更新為C++11標準;
? 第9章 random庫更新為C++11標準;
? 第10章 新增cpu_timer庫,system更新為C++11標準,filesystem更新為V3;
? 第11章 result_of、ref、bind、function等庫更新為C++11標準;
? 第12章 thread庫更新為符合C++11標準的V3(變動非常大);
? 第14章 更新至Boost1.51版;
? 附錄 補充了對C++11標準的簡介,同時刪除了用處不大的網路資和ref_array原始碼。
第1版的版式個人感覺比較滿意,但代碼行多的時候還是不容易閱讀,所以本次對部分重要的代碼片段加粗醒目,用於提醒讀者注意要點。
作者最早的開發環境是Windows,近年來工作重心逐漸轉移,Mac OS X和Linux成了主力工作環境(個人非常欣賞Apple公司),因此第2版中淡化了Windows作業系統的色彩,不再細述VC相關的配置,示範代碼也基本改為UNIX風格,請讀者明鑑。
致謝
同第1版一樣,我首先要感謝Bjarne Stroustrup博士、C++標準委員會和C++/Boost社區,感謝他們長久以來的堅持和努力,為我們帶來了C++11標準和越來越接近完美的Boost程式庫。
然後是我的家人:感謝我的父母、弟弟和妻子,你們永遠是我生命中最重要的人;感謝即將滿4歲的女兒,這本書是和你一同成長起來的,希望你將來能夠讀懂它。
最後感謝讀者選擇本書,希望和您再次一起分享學習C++和Boost的快樂。
羅劍鋒
2012年10月12日於北京 WFC

相關詞條

熱門詞條

聯絡我們