C++ 之美:代碼簡潔、安全又跑得快的 30個要訣 (Beautiful C++: 30 Core Guidelines for Writing Clean, Safe, and Fast Code)

王江平 王江平

買這商品的人也買了...

相關主題

商品描述

本書從《C++核心準則》(C++ Core Guidelines)中精心挑選了 30 條準則進行細致、深入的講解。內容涵蓋C++語言最主要的方面,如類型系統、面向對象、模板和元編程、錯誤處理、程序性能、常量性等,其間又恰如其分地穿插了編碼風格、設計模式等主題。書中匯集了作者數十年職業生涯的經驗和一些有趣的示例,除了深刻的見解,行文也充滿了趣味性。作者試圖通過這種突出重點、以點帶面的方式幫助讀者瞭解並學習《C++核心準則》,進而更深入地掌握 C++這門編程語言,特別是它的"現代”形態。本書適合各種經驗水平的 C++開發者閱讀。

目錄大綱

第1章 避重就輕不可取 1
1.1 P.2:使用ISO標準C++編寫代碼 2
什麽是ISO標準C++ 2
封裝差異 4
瞭解以前的用法 8
緊跟標準的發展 9
1.2 F.51:在有選擇的情況下,優先使用默認參數而非重載 12
引言 12
改進抽象概念:是增加參數還是重載 13
微妙的重載解決 14
回到示例代碼 16
默認參數天然的明確性 18
函數重載的替代方案 19
有時必須重載 19
小結 20
1.3 C.45:不要定義僅初始化數據成員的默認構造函數,而應使用類內成員
?初始化 21
為什麽要有默認構造函數 21
你是怎樣初始化數據成員的 22
兩個人維護一個類時會怎樣 25
小結 27
1.4 C.131:避免平凡的get和set函數 28
一種古老的慣用法 28
抽象 29
單純的封裝 31
類不變式 34
名詞和動詞 36
小結 37
1.5 ES.10:每條語句只聲明一個名字 38
我來引入你 38
向後兼容 40
寫出更加清晰的聲明 42
結構式綁定 43
小結 44
1.6 NR.2:不強求函數只用一條return語句 45
規則會演化 45
確保資源得到清理 47
使用RAII 50
編寫好的函數 52
小結 54
第2章 不要傷害自己 55
2.1 P.11:將凌亂的構造封裝起來,而不是使其散佈於代碼中 56
“一口吞”式做法 56
封裝一種凌亂的構造意味著什麽 58
語言的目的和抽象的本質 60
抽象的層次 63
通過重構和分割實現抽象 64
小結 65
2.2 I.23:盡量減少函數參數 66
他們應該掙多少 66
通過抽象簡化問題 68
盡可能少,但不要更少 70
現實例子 72
小結 73
2.3 I.26:使用C風格子集獲取跨編譯器的ABI 74
創建程序庫 74
什麽是ABI 75
最小的C風格子集 77
異常的傳播 79
小結 80
2.4 C.47:按聲明的順序定義並初始化成員變量 82
小結 90
2.5 CP.3:盡量減少可寫數據的顯式共享 91
傳統執行模型 91
等等,不止這些 93
避免死鎖和數據競爭 95
拋開鎖和互斥體 97
小結 100
2.6 T.120:只在真正需要時使用模板元編程 101
std::enable_if => requires 108
小結 112
第3章 別再使用 113
3.1 I.11:切勿通過原生指針(T*)或引用(T&)轉移所有權 114
使用自由存儲區 114
智能指針的性能成本 117
使用未修飾的引用語義 118
gsl::owner 119
小結 121
3.2 I.3:避免使用單例 122
全局對象是不好的 122
單例設計模式 123
靜態初始化順序的尷尬 123
如何隱藏一個單例 125
但它就該只有一份 127
等一下…… 128
小結 130
3.3 C.90:使用構造函數和賦值運算符,而不是memset和memcpy 131
追求最優性能 131
構造函數的巨大開銷 132
最簡單的類 133
C++標準到底在說什麽 135
那麽,memcpy呢 137
永遠不要低估編譯器 139
小結 140
3.4 ES.50:不要用強制轉換去除const限定符 141
故事時間 141
處理更大的數據量 142
const防火牆 143
實現雙接口 144
緩存和懶惰求值 146
兩種類型的const 147
const驚奇篇 149
小結 150
3.5 E.28:避免基於全局狀態(如errno)的錯誤處理 151
錯誤處理很難 151
C和errno 151
返回錯誤代碼 153
異常 154
<system_error> 154
Boost.Outcome 155
錯誤處理為何這樣難 156
隧道盡頭的光 158
小結 159
3.6 SF.7:不要在頭文件的全局作用域寫using namespace 160
不要這樣做 160
消除歧義 161
使用using 162
符號去了哪裡 163
一個更加隱蔽的問題 166
解決作用域解析運算符的雜亂問題 168
誘惑與墮落 169
小結 169
第4章 正確使用新特性 171
4.1 F.21:優先選擇結構體或元組返回多個“輸出”值 172
函數簽名的形式 172
文檔和註解 173
現在可以返回對象了 174
也可以返回元組 177
使用非const引用傳遞和返回 179
小結 182
4.2 Enum.3:優先選擇class枚舉而不是“普通”枚舉 183
常量 183
作用域枚舉 185
基礎類型 187
隱式轉換 188
小結 190
後記 190
4.3 ES.5:保持作用域短小 191
作用域的性質 191
塊作用域 192
名字空間作用域 193
類作用域 196
函數參數作用域 198
枚舉作用域 199
模板參數作用域 200
作用域作為上下文 201
小結 202
4.4 Con.5:使用constexpr表示編譯時可以計算的值 203
從const到constexpr 203
默認的C++ 205
使用constexpr 206
inline 210
constevel 211
constinit 212
小結 213
4.5 T.1:使用模板提高代碼的抽象層次 214
故事時間 214
提高抽象的層次 216
函數模板和抽象 218
類模板和抽象 220
命名很難 222
小結 223
4.6 T.10:為所有模板參數指定概念 224
來龍去脈 224
約束你的參數 226
如何抽象你的概念 229
通過概念分解 232
小結 233
第5章 默認寫出好代碼 234
5.1 P.4:在理想情況下,程序應具有靜態類型安全性 235
類型安全是C++的一項安全特性 235
聯合體 237
類型轉換 238
無符號數 241
緩沖區和大小 244
小結 245
5.2 P.10:優先選擇不可變量據而不是可變量據 246
錯誤的默認設置 246
函數聲明中的常量性 248
小結 252
5.3 I.30:封裝違反規則的部分 253
隱藏生活中不悅目的東西 253
保全體面 255
小結 260
5.4 ES.22:初始值確定後再聲明變量 261
表達式和語句的重要性 261
C風格的聲明 262
先聲明後初始化 263
盡可能推遲的聲明 264
上下文特定功能的局部化 266
消除狀態 268
小結 270
5.5 Per.7:為促成優化而設計 271
幀率最大化 271
離硬件更遠之後 273
通過抽象進行優化 276
小結 278
5.6 E.6:使用RAII防止泄漏 279
確定性析構 279
文件泄漏 281
為什麽要做這些 284
似乎還是有點兒多:未來的可能性 286
從哪裡獲得這些工具 289
後記 291
跋 293

【C++核心準則精選】
P.2:使用ISO標準C++編寫代碼(1.1節)[ 可以在GitHub或者GitHub Pages上找到C++ Core Guidelines,查看詳細內容。]
P.4:在理想情況下,程序應具有靜態類型安全性(5.1節)
P.10:優先選擇不可變量據而不是可變量據(5.2節)
P.11:將凌亂的構造封裝起來,而不是使其散佈於代碼中(2.1節)
I.3:避免使用單例(3.2節)
I.11:切勿通過原生指針(T*)或引用(T&)轉移所有權(3.1節)
I.23:盡量減少函數參數(2.2節)
I.26:使用C風格子集獲取跨編譯器的ABI(2.3節)
I.30:封裝違反規則的部分(5.3節)
F.21:優先選擇結構體或元組返回多個“輸出”值(4.1節)
F.51:在有選擇的情況下,優先使用默認參數而非重載(1.2節)
C.45:不要定義僅初始化數據成員的默認構造函數,而應該使用類內成員初始化(1.3節)
C.47:按聲明的順序定義並初始化成員變量(2.4節)
C.90:使用構造函數和賦值運算符,而不是memset和memcpy(3.3節)
C.131:避免平凡的get和set函數(1.4節)
Enum.3:優先選擇class枚舉而不是“普通”枚舉(4.2節)
ES.5:保持作用域短小(4.3節)
ES.10:每條語句只聲明一個名字(1.5節)
ES.22:初始值確定後再聲明變量(5.4節)
ES.50:不要用強制轉換去除const限定符(3.4節)
Per.7:為促成優化而設計(5.5節)
CP.3:盡量減少可寫數據的顯式共享(2.5節)
E.6:使用RAII防止泄漏(5.6節)
E.28:避免基於全局狀態(如errno)的錯誤處理(3.5節)
Con.5:使用constexpr表示編譯時可以計算的值(4.4節)
T.1:使用模板提高代碼的抽象層次(4.5節)
T.10:為所有模板參數指定概念(4.6節)
T120:只在真正需要時使用模板元編程(2.6節)
SF.7:不要在頭文件的全局作用域寫using namespace(3.6節)
NR.2:不強求函數只用一條return語句(1.6節)