C++23高級編程(第6版) Professional C++

[比] 馬克·格雷瓜爾(Marc Gregoire)著 王誌強 張興 李暢 何榮華 譯

  • C++23高級編程(第6版)-preview-1
  • C++23高級編程(第6版)-preview-2
  • C++23高級編程(第6版)-preview-3
C++23高級編程(第6版)-preview-1

相關主題

商品描述

"全新修訂的《C++23高級編程》(第6版)延續經典之作的深厚底蘊,由資深軟件工程師Marc Gregoire執筆撰寫,再次為“高階編程”指南樹立新標桿。本書幾乎涵蓋代號為C++23的新標準的所有特性,並通過經Windows與Linux平臺測試的大量實戰代碼案例,提供深入、透徹的解析。 C++的功能極其廣泛,是遊戲和商業軟件中***的高級程序設計語言之一。然而,無法回避的事實是:C++十分復雜,難以掌握。《C++23高級編程(第6版)》將讓C++專業人員能跟上**的發展潮流,保持技術領先。 高效進階C++: 一本助你快速精通C++知識的**指南 作為追求卓越的C++開發者的**資源,本書助你實現以下目標。 ● 精通C++23**特性:精準掌握C++23新標準 ● **化C++潛能:通過高效設計方案釋放性能 ● 規避開發陷阱:揭示冷門知識點與常見反模式 ● 測試與調試之道:學習行業**實踐 ● 性能調優秘籍:掌握提升效率的關鍵技巧"

作者簡介

"Marc Gregoire是一位軟件項目經理/軟件架構師,深耕C/C++開發,尤精Microsoft VC++及MFC框架,擁有開發7×24小時運行於Windows和Linux平臺的C++程序的經驗(如KNX/EIB家庭自動化軟件)。除了C/C++,Marc也擅長C#。 Marc是比利時C++用戶組創始人,暢銷技術圖書Professional C++(第2~6版)的作者,C++ Standard Library Quick Reference(第1~2版)的共同作者,多家出版社多部技術書籍的特約編輯,CppCon C++大會常駐演講嘉賓,CodeGuru論壇成員(用戶名:Marc G)。自2007年以來,他憑借在Visual C++領域的技術影響力,連續十多年榮獲微軟MVP年度獎項。Marc畢業於比利時魯汶大學,先後獲得計算機科學工程碩士學位和AI專業的高級碩士學位。職業生涯初期,Marc加入比利時軟件咨詢公司Ordina,擔任技術顧問,主導開發Siemens 和Nokia Siemens Networks面向電信運營商的關鍵2G/3G系統 (基於Solaris平臺),項目團隊橫跨南美、美國、歐洲、中東、非洲及亞洲多地。Marc現任職於精密光學儀器與工業檢測技術領軍企業尼康計量(Nikon Metrology),負責X射線、CT及三維幾何檢測領域的軟件架構設計與項目管理。"

目錄大綱

目    錄

 

第I部分  專業的C++簡介

第1章  C++和標準庫速成  3

1.1  C++速成  3

1.1.1  小程序“Hello World”  4

1.1.2  命名空間  8

1.1.3  字面量  10

1.1.4  變量  11

1.1.5  運算符  15

1.1.6  枚舉  17

1.1.7  結構體  19

1.1.8  條件語句  20

1.1.9  條件運算符  22

1.1.10  邏輯比較運算符  23

1.1.11  三向比較運算符  24

1.1.12  函數  25

1.1.13  屬性  27

1.1.14  C風格的數組  30

1.1.15  std::array  31

1.1.16  std::vector  32

1.1.17  std::pair  32

1.1.18  std::optional  33

1.1.19  結構化綁定  34

1.1.20  循環  34

1.1.21  初始化列表  36

1.1.22  C++中的字符串  36

1.1.23  作為面向對象語言的C++  36

1.1.24  作用域解析  40

1.1.25  統一初始化  41

1.1.26  指針和動態內存  44

1.1.27  const的用法  47

1.1.28  引用  50

1.1.29  const_cast()  58

1.1.30  異常  59

1.1.31  類型別名  60

1.1.32  類型定義  61

1.1.33  類型推斷  61

1.1.34  標準庫  64

1.2  第一個大型的C++程序  64

1.2.1  雇員記錄系統  64

1.2.2  Employee類  64

1.2.3  Database類  68

1.2.4  用戶界面  70

1.2.5  評估程序  72

1.3  本章小結  73

1.4  練習  73

第2章  使用字符串和字符串視圖  74

2.1  動態字符串  74

2.1.1  C風格字符串  74

2.1.2  字符串字面量  76

2.1.3  C++ std::string類  78

2.1.4  數值轉換  82

2.1.5  std::string_view類  85

2.1.6  非標準字符串  87

2.2  字符串格式化與打印  87

2.2.1  格式字符串  88

2.2.2  參數索引  89

2.2.3  打印到不同的目的地  89

2.2.4  格式字符串的編譯期驗證  90

2.2.5  格式說明符  91

2.2.6  格式化轉義字符和字符串  94

2.2.7  格式化範圍  94

2.2.8  支持自定義類型  96

2.3  本章小結  99

2.4  練習  99

第3章  編碼風格  101

3.1  良好外觀的重要性  101

3.1.1  事先考慮  101

3.1.2  良好風格的元素  102

3.2  為代碼編寫文檔  102

3.2.1  使用註釋的原因  102

3.2.2  註釋的風格  106

3.3  分解  109

3.3.1  通過重構分解  110

3.3.2  通過設計分解  111

3.3.3  本書中的分解  111

3.4  命名  111

3.4.1  選擇恰當的名稱  111

3.4.2  命名約定  112

3.5  使用具有風格的語言特性  113

3.5.1  使用常量  114

3.5.2  使用引用代替指針  114

3.5.3  使用自定義異常  115

3.6  格式  115

3.6.1  關於大括號對齊的爭論  115

3.6.2  關於空格和圓括號的爭論  116

3.6.3  空格、制表符、換行符  117

3.7  風格的挑戰  117

3.8  本章小結  117

3.9  練習  118

 

第II部分  專業的C++軟件設計

第4章  設計專業的C++程序  123

4.1  程序設計概述  123

4.2  程序設計的重要性  124

4.3  C++設計  126

4.4  C++設計的兩個原則  126

4.4.1  抽象  126

4.4.2  重用  128

4.5  重用現有代碼  130

4.5.1  關於術語的說明  130

4.5.2  決定是否重用代碼  130

4.5.3  重用代碼的指導原則  132

4.6  設計一個國際象棋程序  137

4.6.1  需求  137

4.6.2  設計步驟  138

4.7  本章小結  143

4.8  練習  143

第5章  面向對象設計  145

5.1  過程化的思考方式  145

5.2  面向對象思想  146

5.2.1  類  146

5.2.2  組件  146

5.2.3  屬性  147

5.2.4  行為  147

5.2.5  綜合考慮  147

5.3  生活在類的世界裏  148

5.3.1  過度使用類  148

5.3.2  過於通用的類  149

5.4  類之間的關系  150

5.4.1  “有一個”關系  150

5.4.2  “是一個”關系(繼承)  150

5.4.3  “有一個”與“是一個”的區別  152

5.4.4  not-a關系  155

5.4.5  層次結構  155

5.4.6  多重繼承  156

5.4.7  混入類  157

5.5  本章小結  158

5.6  練習  158

第6章  設計可重用代碼  160

6.1  重用哲學  160

6.2  如何設計可重用代碼  161

6.2.1  使用抽象  161

6.2.2  構建理想的重用代碼  162

6.2.3  設計有用的接口  168

6.2.4  設計成功的抽象  173

6.2.5  SOLID原則  174

6.3  本章小結  174

6.4  練習  175

 

第III部分  C++編碼方法

第7章  內存管理  179

7.1  使用動態內存  180

7.1.1  如何描繪內存  180

7.1.2  分配和釋放  181

7.1.3  數組  183

7.1.4  使用指針  189

7.2  數組-指針的對偶性  190

7.2.1  數組退化為指針  190

7.2.2  並非所有指針都是數組  192

7.3  底層內存操作  192

7.3.1  指針運算  192

7.3.2  自定義內存管理  193

7.3.3  垃圾回收  194

7.3.4  對象池  194

7.4  常見的內存陷阱  194

7.4.1  數據緩沖區分配不足以及內存訪問越界  194

7.4.2  內存泄漏  196

7.4.3  雙重釋放和無效指針  198

7.5  智能指針  199

7.5.1  unique_ptr  199

7.5.2  shared_ptr  202

7.5.3  weak_ptr  205

7.5.4  向函數傳遞參數  206

7.5.5  從函數中返回  206

7.5.6  enable_shared_from_this  207

7.5.7  智能指針與C風格函數的交互  207

7.5.8  過時的、移除的auto_ptr  208

7.6  本章小結  208

7.7  練習  208

第8章  熟悉類和對象  210

8.1  電子表格示例介紹  210

8.2  編寫類  211

8.2.1  類定義  211

8.2.2  定義方法  213

8.2.3  使用對象  215

8.2.4  this指針  217

8.2.5  顯式對象參數  218

8.3  對象的生命周期  218

8.3.1  創建對象  218

8.3.2  銷毀對象  233

8.3.3  對象賦值  234

8.3.4  編譯器生成的拷貝構造函數和拷貝賦值運算符  237

8.3.5  復制和賦值的區別  237

8.4  本章小結  238

8.5  練習  239

第9章  精通類和對象  240

9.1  友元  240

9.2  對象中的動態內存分配  241

9.2.1  Spreadsheet類  241

9.2.2  使用析構函數釋放內存  244

9.2.3  處理復制和賦值  245

9.2.4  使用移動語義處理移動  250

9.2.5  零規則  260

9.3  與成員函數有關的更多內容  261

9.3.1  static成員函數  261

9.3.2  const成員函數  262

9.3.3  成員函數重載  263

9.3.4  內聯成員函數  267

9.3.5  默認參數  268

9.4  constexpr與consteval  269

9.4.1  constexpr關鍵字  269

9.4.2  consteval關鍵字  270

9.4.3  constexpr 和 consteval 類  271

9.5  不同的數據成員類型  272

9.5.1  靜態數據成員  272

9.5.2  const static數據成員  274

9.5.3  引用數據成員  274

9.6  嵌套類  276

9.7  類內的枚舉類型  277

9.8  運算符重載  277

9.8.1  示例:為SpreadsheetCell實現加法  278

9.8.2  重載算術運算符  281

9.8.3  重載比較運算符  282

9.9  創建穩定的接口  286

9.10  本章小結  289

9.11  練習  290

第10章  揭秘繼承技術  291

10.1  使用繼承構建類  291

10.1.1  擴展類  292

10.1.2  重寫成員函數  295

10.2  使用繼承重用代碼  302

10.2.1  WeatherPrediction類  302

10.2.2  在派生類中添加功能  303

10.2.3  在派生類中替換功能  304

10.3  利用父類  305

10.3.1  父類構造函數  305

10.3.2  父類的析構函數  306

10.3.3  構造函數和析構函數中的虛成員函數調用  307

10.3.4  使用父類成員函數  308

10.3.5  向上轉型和向下轉型  310

10.4  繼承與多態性  311

10.4.1  回到電子表格  311

10.4.2  設計多態性的電子表格單元格  311

10.4.3  SpreadsheetCell基類  312

10.4.4  獨立的派生類  313

10.4.5  利用多態性  315

10.4.6  考慮將來  316

10.4.7  提供純虛成員函數的實現  317

10.5  多重繼承  318

10.5.1  從多個類繼承  318

10.5.2  名稱沖突和歧義基類  319

10.6  有趣而晦澀的繼承問題  321

10.6.1  修改重寫成員函數的返回類型  322

10.6.2  派生類中添加虛基類成員函數的重載  324

10.6.3  繼承的構造函數  325

10.6.4  重寫成員函數時的特殊情況  328

10.6.5  派生類中的拷貝構造函數和賦值運算符  334

10.6.6  運行時類型工具  335

10.6.7  非public繼承  337

10.6.8  虛基類  337

10.7  類型轉換  340

10.7.1  static_cast()  340

10.7.2  reinterpret_cast()  341

10.7.3  dynamic_cast()  342

10.7.4  std::bit_cast()  343

10.7.5  類型轉換小結  343

10.8  本章小結  344

10.9  練習  344

第11章  模塊、頭文件和其他主題  345

11.1  模塊  345

11.1.1  非模塊化代碼  346

11.1.2  標準命名模塊  346

11.1.3  模塊接口文件  347

11.1.4  模塊實現文件  348

11.1.5  從實現中分離接口  349

11.1.6  可見性和可訪問性  350

11.1.7  子模塊  350

11.1.8  模塊劃分  351

11.1.9  私有模塊片段  353

11.1.10  頭文件單元  355

11.1.11  可導入的標準庫頭文件  355

11.2  預處理指令  357

11.3  鏈接  358

11.3.1  內部鏈接  359

11.3.2  extern 關鍵字  360

11.4  頭文件  361

11.4.1  單一定義規則(ODR)  361

11.4.2  重復定義  361

11.4.3  循環依賴  362

11.4.4  查詢頭文件是否存在  363

11.4.5  模塊導入聲明  363

11.5  核心語言特性的特性測試宏  363

11.6  static關鍵字  364

11.6.1  靜態數據成員和成員函數  364

11.6.2  函數中的靜態變量  364

11.6.3  非局部變量的初始化順序  365

11.6.4  非局部變量的銷毀順序  365

11.7  C 風格的可變長度參數列表  365

11.7.1  訪問參數  366

11.7.2  為什麼不應該使用C風格的變長參數列表  367

11.8  本章小結  367

11.9  練習  367

第12章  利用模板編寫泛型代碼  369

12.1  模板概述  370

12.2  類模板  370

12.2.1  編寫類模板  370

12.2.2  編譯器處理模板的原理  378

12.2.3  將模板代碼分布到多個文件中  379

12.2.4  模板參數  380

12.2.5  成員函數模板  383

12.2.6  類模板的特化  389

12.2.7  從類模板派生  391

12.2.8  繼承還是特化  392

12.2.9  模板別名  392

12.3  函數模板  393

12.3.1  函數重載與函數模板  394

12.3.2  函數模板的重載  394

12.3.3  類模板的友元函數模板  395

12.3.4  對模板參數推導的更多介紹  397

12.3.5  函數模板的返回類型  397

12.3.6  簡化函數模板的語法  399

12.4  變量模板  399

12.5  概念  400

12.5.1  語法  400

12.5.2  約束表達式  401

12.5.3  預定義的標準概念  403

12.5.4  類型約束的auto  404

12.5.5  類型約束和函數模板  404

12.5.6  類型約束和類模板  407

12.5.7  類型約束和類成員函數  407

12.5.8  基於約束的類模板特化和函數模板重載  408

12.5.9  最佳實踐  408

12.6  本章小結  409

12.7  練習  409

第13章  C++ I/O揭秘  410

13.1  使用流  411

13.1.1  流的含義  411

13.1.2  流的來源和目的地  412

13.1.3  流式輸出  412

13.1.4  流式輸入  417

13.1.5  對象的輸入輸出  423

13.1.6  自定義的操作算子  424

13.2  字符串流  425

13.3  基於span的流  426

13.4  文件流  427

13.4.1  文本模式與二進制模式  428

13.4.2  通過seek()和tell()在文件中轉移  428

13.4.3  將流鏈接在一起  430

13.4.4  讀取整個文件  431

13.5  雙向I/O  431

13.6  文件系統支持庫  432

13.6.1  路徑  432

13.6.2  目錄條目  434

13.6.3  輔助函數  434

13.6.4  目錄遍歷  434

13.7  本章小結  435

13.8  練習  436

第14章  錯誤處理  437

14.1  錯誤與異常  437

14.1.1  異常的含義  438

14.1.2  C++中異常的優點  438

14.1.3  建議  439

14.2  異常機制  439

14.2.1  拋出和捕獲異常  440

14.2.2  異常類型  442

14.2.3  按const引用捕獲異常對象  443

14.2.4  拋出並捕獲多個異常  443

14.2.5  未捕獲的異常  446

14.2.6  noexcept說明符  447

14.2.7  noexcept(expression)說明符  448

14.2.8  noexcept(expression)運算符  448

14.2.9  拋出列表  448

14.3  異常與多態性  449

14.3.1  標準異常層次結構  449

14.3.2  在類層次結構中捕獲異常  450

14.3.3  編寫自己的異常類  451

14.3.4  嵌套異常  453

14.4  重新拋出異常  455

14.5  棧的釋放與清理  456

14.5.1  使用智能指針  458

14.5.2  捕獲、清理並重新拋出  458

14.6  源碼位置  459

14.6.1  日誌記錄的源碼位置  459

14.6.2  在自定義異常中自動嵌入源位置  460

14.7  堆棧跟蹤  461

14.7.1  堆棧跟蹤庫  461

14.7.2  在自定義異常中自動嵌入堆棧跟蹤  462

14.8  常見的錯誤處理問題  464

14.8.1  內存分配錯誤  464

14.8.2  構造函數中的錯誤  466

14.8.3  構造函數的function-try-blocks  468

14.8.4  析構函數中的錯誤  470

14.9  異常安全保證  471

14.10  本章小結  471

14.11  練習  471

第15章  C++運算符重載  473

15.1  運算符重載概述  473

15.1.1  重載運算符的原因  474

15.1.2  運算符重載的限制  474

15.1.3  運算符重載的選擇  474

15.1.4  不應重載的運算符  476

15.1.5  可重載運算符小結  476

15.1.6  右值引用  479

15.1.7  優先級和結合性  480

15.1.8  關系運算符  481

15.1.9  替代符號  481

15.2  重載算術運算符  482

15.2.1  重載一元負號和一元正號運算符  482

15.2.2  重載遞增和遞減運算符  482

15.3  重載按位運算符和二元邏輯運算符  483

15.4  重載插入運算符和提取運算符  483

15.5  重載下標運算符  485

15.5.1  通過operator[]提供只讀訪問  488

15.5.2  多維下標運算符  489

15.5.3  非整數數組索引  490

15.5.4  靜態下標運算符  490

15.6  重載函數調用運算符  491

15.7  重載解除引用運算符  492

15.7.1  實現operator*  494

15.7.2  實現operator->  494

15.7.3  operator.*和operator ->*的含義  494

15.8  編寫轉換運算符  495

15.8.1  auto運算符  496

15.8.2  使用顯式轉換運算符解決多義性問題  496

15.8.3  用於布爾表達式的轉換  497

15.9  重載內存分配和內存釋放運算符  498

15.9.1  new和delete的工作原理  499

15.9.2  重載operator new和operator delete  500

15.9.3  顯式地刪除/默認化operator new和operator delete  502

15.9.4  重載帶有額外參數的operator new和operator delete  502

15.9.5  重載帶有內存大小參數的operator delete  503

15.10  重載用戶定義的字面量運算符  504

15.10.1  標準庫定義的字面量  504

15.10.2  用戶自定義的字面量  504

15.11  本章小結  506

15.12  練習  506

第16章  C++標準庫概述  508

16.1  編碼原則  509

16.1.1  使用模板  509

16.1.2  使用運算符重載  509

16.2  C++標準庫概述  509

16.2.1  字符串  509

16.2.2  正則表達式  510

16.2.3  I/O流  510

16.2.4  智能指針  510

16.2.5  異常  510

16.2.6  標準整數類型  511

16.2.7  數學工具  511

16.2.8  整數比較  512

16.2.9  位操作  512

16.2.10  時間和日期工具  513

16.2.11  隨機數  513

16.2.12  初始化列表  513

16.2.13  Pair和Tuple  513

16.2.14  詞匯類型  513

16.2.15  函數對象  514

16.2.16  文件系統  514

16.2.17  多線程  514

16.2.18  類型萃取  514

16.2.19  標準庫特性測試宏  514

16.2.20  <version>  515

16.2.21  源位置  516

16.2.22  堆棧跟蹤  516

16.2.23  容器  516

16.2.24  算法  522

16.2.25  範圍庫  529

16.2.26  標準庫中還缺什麼  530

16.3  本章小結  530

16.4  練習  530

第17章  理解疊代器與範圍庫  532

17.1  疊代器  532

17.1.1  獲取容器的疊代器  534

17.1.2  疊代器萃取  536

17.1.3  示例  536

17.1.4  使用疊代器特性進行函數分發  537

17.2  流疊代器  539

17.2.1  輸出流疊代器:ostream_iterator  539

17.2.2  輸入流疊代器:istream_iterator  540

17.2.3  輸入流疊代器:istreambuf_iterator  540

17.3  疊代器適配器  540

17.3.1  插入疊代器  541

17.3.2  逆向疊代器  542

17.3.3  移動疊代器  543

17.4  範圍  544

17.4.1  約束算法  545

17.4.2  視圖  547

17.4.3  範圍工廠  552

17.4.4  將範圍轉換為容器  554

17.5  本章小結  555

17.6  練習  556

第18章  標準庫容器  557

18.1  容器概述  557

18.1.1  對元素的要求  558

18.1.2  異常和錯誤檢查  559

18.2  順序容器  559

18.2.1  vector  560

18.2.2  vector<bool>特化  578

18.2.3  deque  578

18.2.4  list  579

18.2.5  forward_list  581

18.2.6  array  584

18.3  順序視圖  585

18.3.1  span  585

18.3.2  mdspan  587

18.4  容器適配器  588

18.4.1  queue  588

18.4.2  priority_queue  591

18.4.3  stack  593

18.5  關聯容器  593

18.5.1  有序關聯容器  594

18.5.2  無序關聯容器/哈希表  607

18.5.3  平坦集合和平坦映射關聯容器適配器  613

18.5.4  關聯容器的性能  614

18.6  其他容器  614

18.6.1  標準C風格數組  614

18.6.2  string  615

18.6.3  流  615

18.6.4  bitset  616

18.7  本章小結  620

18.8  練習  620

第19章  函數指針、函數對象、lambda表達式  622

19.1  函數指針  622

19.1.1  findMatches() 使用函數指針  623

19.1.2  findMatches() 函數模板  624

19.1.3  Windows DLL和函數指針  625

19.2  指向成員函數(和數據成員)的指針  626

19.3  函數對象  627

19.3.1  編寫第一個函數對象  627

19.3.2  標準庫中的函數對象  627

19.4  多態功能包裝器  634

19.4.1  std::function  634

19.4.2  std::move_only_function  635

19.5  lambda表達式  636

19.5.1  語法  636

19.5.2  lambda表達式作為參數  640

19.5.3  泛型lambda表達式  641

19.5.4  lambda捕獲表達式  641

19.5.5  模板化lambda表達式  642

19.5.6  lambda 表達式作為返回類型  643

19.5.7  未計算上下文中的lambda表達式  643

19.5.8  默認構造、拷貝和賦值  643

19.5.9  遞歸lambda表達式  644

19.6  調用  644

19.7  本章小結  645

19.8  練習  645

第20章  掌握標準庫算法  647

20.1  算法概述  647

20.1.1  find() 和 find_if() 算法  648

20.1.2  accumulate() 算法  650

20.1.3  在算法中使用移動語義  651

20.1.4  算法回調  651

20.2  算法詳解  652

20.2.1  非修改序列算法  652

20.2.2  修改序列算法  657

20.2.3  操作算法  665

20.2.4  分區算法  667

20.2.5  排序算法  668

20.2.6  二分查找算法  669

20.2.7  集合算法  670

20.2.8  最小/最大算法  672

20.2.9  並行算法  673

20.2.10  數值處理算法  674

20.2.11  約束算法  676

20.3  本章小結  678

20.4  練習  678

第21章  字符串的本地化與正則表達式  680

21.1  本地化  680

21.1.1  寬字符  680

21.1.2  非西方字符集  681

21.1.3  本地化字符串字面量  683

21.1.4  locale和facet  683

21.2  正則表達式  688

21.2.1  ECMAScript語法  689

21.2.2  regex庫  693

21.2.3  regex_match()  694

21.2.4  regex_search()  696

21.2.5  regex_iterator  697

21.2.6  regex_token_iterator  698

21.2.7  regex_replace()  700

21.3  本章小結  702

21.4  練習  702

第22章  日期和時間工具  704

22.1  編譯期有理數  704

22.2  持續時間  706

22.2.1  示例與duration轉換  707

22.2.2  預定義的duration  709

22.2.3  標準字面量  710

22.2.4  hh_mm_ss  710

22.3  時鐘  710

22.3.1  打印當前時間  711

22.3.2  執行時間  712

22.4  時間點  712

22.5  日期  714

22.5.1  創建日期  714

22.5.2  打印日期  716

22.5.3  日期運算  717

22.6  時區  717

22.7  本章小結  718

22.8  練習  719

第23章  隨機數工具  720

23.1  C風格隨機數生成器  720

23.2  隨機數引擎  721

23.3  隨機數引擎適配器  722

23.4  預定義的隨機數引擎和引擎適配器  723

23.5  生成隨機數  723

23.6  隨機數分布  725

23.7  本章小結  728

23.8  練習  728

第24章  其他詞匯類型  729

24.1  variant  729

24.2  any  731

24.3  元組  732

24.3.1  分解元組  734

24.3.2  串聯  735

24.3.3  比較  736

24.3.4  make_from_tuple()  737

24.3.5  apply()  737

24.4  optional:單子式操作  737

24.5  expected  738

24.6  本章小結  741

24.7  練習  741

 

第IV部分  掌握C++的高級特性

第25章  自定義和擴展標準庫  745

25.1  分配器  745

25.2  擴展標準庫  746

25.2.1  擴展標準庫的原因  747

25.2.2  編寫標準庫算法  747

25.2.3  編寫標準庫容器  749

25.3  本章小結  773

25.4  練習  774

第26章  高級模板  775

26.1  深入了解模板參數  775

26.1.1  深入了解模板類型參數  775

26.1.2  template template參數介紹  778

26.1.3  深入了解非類型模板參數  780

26.2  類模板部分特化  781

26.3  通過重載模擬函數部分特化  784

26.4  模板遞歸  785

26.4.1  N維網格:初次嘗試  786

26.4.2  真正的N維網格  786

26.5  變參模板  788

26.5.1  類型安全的變長參數列表  788

26.5.2  可變數目的混入類  791

26.5.3  折疊表達式  792

26.6  模板元編程  794

26.6.1  編譯期階乘  794

26.6.2  循環展開  795

26.6.3  打印元組  795

26.6.4  類型萃取  798

26.6.5  模板元編程總結  809

26.7  本章小結  809

26.8  練習  809

第27章  C++多線程編程  810

27.1  多線程編程概述  811

27.1.1  爭用條件  812

27.1.2  撕裂  813

27.1.3  死鎖  813

27.1.4  偽共享  814

27.2  線程  815

27.2.1  通過函數指針創建線程  815

27.2.2  通過函數對象創建線程  816

27.2.3  通過lambda創建線程  817

27.2.4  通過成員函數指針創建線程  818

27.2.5  線程本地存儲  818

27.2.6  取消線程  819

27.2.7  自動join線程  819

27.2.8  從線程獲得結果  820

27.2.9  復制和重新拋出異常  821

27.3  原子操作庫  823

27.3.1  原子操作  825

27.3.2  原子智能指針  826

27.3.3  原子引用  826

27.3.4  使用原子類型  826

27.3.5  等待原子變量  828

27.4  互斥  829

27.4.1  互斥量類  829

27.4.2  鎖  831

27.4.3  std::call_once  834

27.4.4  互斥量的用法示例  835

27.5  條件變量  838

27.5.1  虛假喚醒  839

27.5.2  使用條件變量  839

27.6  latch  840

27.7  barrier  841

27.8  semaphore  843

27.9  future  843

27.9.1  std::promise和std::future  844

27.9.2  std::packaged_task  845

27.9.3  std::async  845

27.9.4  異常處理  846

27.9.5  std::shared_future  847

27.10  示例:多線程的Logger類  848

27.11  線程池  852

27.12  協程  852

27.13  線程設計和最佳實踐  854

27.14  本章小結  855

27.15  練習  855

 

第V部分  C++軟件工程

第28章  充分利用軟件工程方法  859

28.1  過程的必要性  859

28.2  軟件生命周期模型  860

28.2.1  瀑布模型  860

28.2.2  生魚片模型  862

28.2.3  螺旋類模型  862

28.2.4  敏捷  864

28.3  軟件工程方法論  865

28.3.1  Scrum  865

28.3.2  UP  867

28.3.3  RUP  868

28.3.4  極限編程  869

28.3.5  軟件分流  872

28.4  構建自己的過程和方法  873

28.4.1  對新思想采取開放態度  873

28.4.2  提出新想法  873

28.4.3  知道什麼行得通、什麼行不通  873

28.4.4  不要逃避  873

28.5  版本控制  873

28.6  本章小結  875

28.7  練習  875

第29章  編寫高效的C++程序  876

29.1  性能和效率概述  876

29.1.1  提升效率的兩種方式  877

29.1.2  兩種程序  877

29.1.3  C++是不是低效的語言  877

29.2  語言層次的效率  877

29.2.1  高效地操縱對象  878

29.2.2  預分配內存  881

29.2.3  使用內聯函數  881

29.2.4  標記無法訪問的代碼  881

29.3  設計層次的效率  882

29.3.1  盡可能多地緩存  882

29.3.2  使用對象池  883

29.4  剖析  888

29.4.1  使用gprof的剖析示例  888

29.4.2  使用Visual C++ 2022的剖析示例  895

29.5  本章小結  897

29.6  練習  897

第30章  熟練掌握測試技術  898

30.1  質量控制  899

30.1.1  誰負責測試  899

30.1.2  bug的生命周期  899

30.1.3  bug跟蹤工具  900

30.2  單元測試  901

30.2.1  單元測試方法  902

30.2.2  單元測試過程  902

30.2.3  實際中的單元測試  905

30.3  模糊測試  912

30.4  高級測試  913

30.4.1  集成測試  913

30.4.2  系統測試  914

30.4.3  回歸測試  914

30.5  用於成功測試的建議  915

30.6  本章小結  915

30.7  練習  916

第31章  熟練掌握調試技術  917

31.1  調試的基本定律  917

31.2  bug分類學  918

31.3  避免bug  918

31.4  為bug做好規劃  919

31.4.1  錯誤日誌  919

31.4.2  調試跟蹤  920

31.4.3  斷言  927

31.4.4  崩潰轉儲  928

31.5  調試技術  928

31.5.1  重現bug  928

31.5.2  調試可重復的bug  929

31.5.3  調試不可重現的bug  929

31.5.4  調試退化  930

31.5.5  調試內存問題  930

31.5.6  調試多線程程序  934

31.5.7  調試示例:文章引用  934

31.5.8  從ArticleCitations示例中總結出的教訓  945

31.6  本章小結  946

31.7  練習  946

第32章  使用設計技術和框架  948

32.1  容易忘記的語法  949

32.1.1  編寫類  949

32.1.2  派生類  950

32.1.3  編寫lambda表達式  951

32.1.4  使用“復制和交換”慣用語法  951

32.1.5  拋出和捕獲異常  952

32.1.6  寫入類模板  953

32.1.7  約束模板參數  953

32.1.8  寫入文件  954

32.1.9  讀取文件  954

32.2  始終存在更好的方法  955

32.2.1  RAII  955

32.2.2  雙分派  958

32.2.3  混入類  961

32.3  面向對象的框架  965

32.3.1  使用框架  965

32.3.2  MVC範型  966

32.4  本章小結  967

32.5  練習  967

第33章  應用設計模式  968

33.1  策略模式  969

33.1.1  示例:日誌機制  969

33.1.2  基於策略logger的實現  969

33.1.3 使用基於策略的Logger  970

33.2  抽象工廠模式  971

33.2.1  示例:模擬汽車工廠  971

33.2.2  實現抽象工廠  972

33.2.3  使用抽象工廠  973

33.3  工廠方法模式  974

33.3.1  示例:模擬第二個汽車工廠  974

33.3.2  實現工廠的方法  975

33.3.3  使用工廠方法  976

33.3.4  其他用法  978

33.4  其他工廠模式  978

33.5  適配器模式  979

33.5.1  示例:適配Logger類  979

33.5.2  實現適配器  980

33.5.3  使用適配器  981

33.6  代理模式  981

33.6.1  示例:隱藏網絡連接問題  981

33.6.2  實現代理  981

33.6.3  使用代理  982

33.7  疊代器模式  983

33.8  觀察者模式  983

33.8.1  示例:從主題中暴露事件  983

33.8.2  實現觀察者  984

33.8.3  使用觀察者  985

33.9  裝飾器模式  986

33.9.1  示例:在網頁中定義樣式  986

33.9.2  裝飾器的實現  987

33.9.3  使用裝飾器  988

33.10  責任鏈模式  988

33.10.1  示例:事件處理  989

33.10.2  實現責任鏈  989

33.10.3  使用責任鏈  990

33.11  單例模式  991

33.11.1  日誌記錄機制  992

33.11.2  實現單例  992

33.11.3  使用單例  994

33.12  本章小結  994

33.13  練習  994

第34章  開發跨平臺和跨語言的應用程序  996

34.1  跨平臺開發  996

34.1.1  架構問題  997

34.1.2  實現問題  999

34.1.3  平臺專用功能  1001

34.2  跨語言開發  1002

34.2.1  混用C和C++  1002

34.2.2  改變範型  1002

34.2.3  鏈接C代碼  1005

34.2.4  從C#調用C++代碼  1006

34.2.5  在C++中使用C#代碼及在C#中使用C++代碼  1008

34.2.6  在Java中使02用JNI調用C++代碼  1009

34.2.7  從C++代碼調用腳本  1011

34.2.8  從腳本調用C++代碼  1011

34.2.9  從C++調用匯編代碼  1013

34.3  本章小結  1014

34.4  練習  1014

 

——以下內容可掃封底二維碼下載——

第VI部分  附錄

附錄A  C++面試  1019

附錄B  參考文獻及相關介紹  1039

附錄C  標準庫頭文件  1048

附錄D  UML簡介  1054