本系列文章記載學習一門在線課程 羅劍鋒的C++實戰筆記 過程中的心得體會,只會記錄新增加的知識點,那些心中已熟透的知識點,不會重複記錄。
c++
的主戰場在 Linux
上,現在開發 Windows
程序,更多的是用 C#
等語言。
後續以問答的形式,來梳理彙總新掌握的注意事項和經驗教訓。
三句名言鎮樓
-
任何人都能寫出機器能看懂的代碼,只有優秀的程序員才能寫出人看懂的代碼
-
兩種寫程序的方式:把代碼寫的非常複雜,以至於"看不出明顯錯誤"。把代碼寫的非常簡單,以至於"明顯看不出錯誤"。
-
把正確的代碼改快速,要比把快速的代碼改正確,容易得太多。
如何查看gcc對c++標準的支持情況?
- 通過
g++ -v
得到g++
版本號。例如:本機版本號爲gcc version 7.5.0
- 下圖爲不同
gcc
版本對C++
標準的支持情況。
更爲具體的,可以參考 C++ Standars Supprot in GCC 網站,查看各個標準在各個編譯器的支持情況。
C++有哪些編程範式?
編程範式是指導編寫代碼的思路、規則、習慣和常用方法的統稱,是一種方法論
。
現代C++
(C++11
以後)支持以下五種編程範式:
- 面向過程:
if
、else
、switch
,核心是功能分解爲具體步驟,依次執行這些步驟。 - 面向對象:
class
、public
、virtual
, 核心是功能抽象爲各種類,將數據以及職責封裝進對應類,通過類對象之間的協作實現功能。以抽象和封裝爲基礎,繼續抽象對象之間的關係和通信,最後構成由許多相關聯的對象系統。 - 泛型:
template
、vector
,核心是將類型當做參數,利用模板來複用代碼。 - 模板元編程:
template
、struct
、enable_if
,核心是編譯期間類型運算,代碼由編譯器執行。 - 函數式:
lambda
,核心是一切皆函數,皆可調用。
日常工程開發中,使用 面向對象
+泛型
,少量函數式
,不用模板元
。
代碼規範
留白: 恰當地運用空格和空行,空格用來分隔變量和操作符,空行用來分隔邏輯代碼塊,使得整體錯落有致,舒緩得當,更易理解。
註釋:正確、清晰、簡潔。從使用者和閱讀者的角度出發,來看待註釋。
類設計:少用繼承,多用組合。控制繼承的層次,用 UML
類圖來主觀檢查。
接口設計:簡單直接,只負責單一功能。
預處理過程中需要注意的地方
- 宏是沒有作用域的,默認全局生效。爲避免宏定義衝突,有兩種解決方法:
- 使用完後使用
#undef
來取消宏定義
#define CUBE(a) (a) * (a) * (a) cout << CUBE(a); #undef CUBE
- 在使用前,先進行檢查。如果之前有定義,則取消定義。
#ifdef AUTH_PWD # undef AUTH_PWD #endif #define AUTH_PWD "XXX"
- 使用完後使用
編譯階段能做的事
屬性標籤
C++11
使用兩對方掛號的形式 [[ ... ]]
,方掛號中間是屬性標籤。deprecated
的編譯期標籤,標記已廢棄的變量、函數。
[[deprecated("deadline:xxxx")]]
int old_fun()
{}
常用的屬性標籤:
unused
: 用於變量、類型和函數等,表示暫時不用,但最好保留constructor
: 指示函數會在main
函數之前執行destructor
: 指示函數會在main
函數之後執行always_inline
: 要求編譯器強制內聯hot
: 標記爲熱點函數,可更積極優化noreturn
: 指示函數不會有返回值
靜態斷言
常用的assert
函數只能在運行期生效,對應的,在編譯期生效的斷言爲 static_assert
,將檢測時機提前到編譯期。
標準庫的 type_traits
,它提供了各種編譯期函數,可進行更爲細緻的判斷。
特殊功能標示符
final
標識符用於類定義,可顯式禁用繼承。
= default
標識類的基本函數由編譯器實現。
自動類型推導
auto
總是推導出值類型,可附加const
、volatile
、&
類型修飾符,得到新的類型。
auto x= 10L; // 推導爲 long
auto& x1 = 1; //推導爲 long&
auto* x2 = &x; // 推導爲 long*
const auto& x3 = x; // 推導爲 const long&
decltype
的形式類似於函數,後面的圓括號用於計算類型的表達式。它不僅能推導出值類型,還能夠推導出引用類型。
自我總結: auto
是從值來推導數據類型,decltype
是從變量自身來推導數據類型。