首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Google C++ 風格指南(一):標頭檔設計與相依性控制

     編輯:關於C++

指南緣起:驯服 C++ 的複雜性

Google 開源專案廣泛採用 C++,但其強大特性伴隨著高複雜度,易導致 Bug 滋生、難以閱讀維護。本指南旨在透過具體編碼規範,在保留語言表達力的前提下,提升程式碼可管理性。核心哲學有二:

  1. 一致性至上:統一風格讓「模式匹配」成為可能,降低認知負荷;除非有極強理由,否則堅持既定慣例。
  2. 特性節制:C++ 特性龐雜,指南明確限制/禁止特定高風險特性(如多重繼承、RTTI、異常),以換取簡潔與穩定。

一、標頭檔防衛:#define 守衛

所有 .h 必須有防重複包含巨集,命名格式:<PROJECT>_<PATH>_<FILE>_H_,確保全域唯一性。範例:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
// ... 內容
#endif // FOO_BAR_BAZ_H_

二、前置宣告:斬斷編譯相依鏈

原則:能用前置宣告(class Foo;)就別 #include "foo.h"。包含標頭檔會引入編譯相依,任何變更皆觸發連鎖重編譯。

何時可用前置宣告?

  • 資料成員為指標/參考(Foo*, Foo&)
  • 函式參數/回傳型別為 Foo 且僅宣告不定義
  • 靜態資料成員型別為 Foo(定義在類別外部)

何時必須包含標頭?

  • 繼承 Foo(子類別)
  • 擁有 Foo 型別非靜態資料成員(需知大小/佈局)

權衡:為減少包含而改用指標成員(如 scoped_ptr)會犧牲可讀性與效率,若僅為少包含標頭則不划算。.cc 檔無論如何都需完整定義,故包含標頭無妨。

三、內聯函數:短小精悍才內聯

  • 僅當函式 不超過 10 行 時考慮 inline。
  • 優點:小型存取函式/熱點函式內聯可減少呼叫開銷、提升指令快取命中率。
  • 缺點:濫用導致目標碼膨脹,反而拖慢執行速度。
  • 禁忌:虛函式、遞迴函式、含迴圈/switch 的函式(除非極少執行)、解構函式(隱含基類/成員解構常超過 10 行)。

四、-inl.h 檔案:複雜內聯的歸宿

  • 內聯函式定義若較長/複雜,置於 -inl.h(如 foo-inl.h),而非汙染主標頭檔。
  • 同樣需 #define 守衛。
  • 也適用於函式樣板定義,提升可讀性。

五、函式參數順序:輸入在前,輸出在後

  • 輸入參數(傳值/const 參考)置前,輸出/輸入輸出參數(非 const 指標)置後。
  • 新增參數亦須遵循此序,不可單純附加在末尾。
  • 輸入輸出兩用參數(類別/結構體)較難套用,視情況調整。

六、包含順序標準化:消除隱藏相依

標準順序:

  1. 對應的 .h(最優先,確保獨立編譯)
  2. C 系統標頭(<stdio.h> 等)
  3. C++ 系統標頭(<vector> 等)
  4. 其他函式庫標頭
  5. 專案內部標頭(依專案目錄樹路徑,禁用 ./ ../)
// 範例:foo/internal/fooserver.cc
#include "foo/public/fooserver.h"  // 對應標頭優先
#include 
#include 
#include 
#include 
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"

同目錄標頭按字母序排列。此規範確保每個標頭檔可獨立編譯,內部錯誤優先暴露。

總結

標頭檔規範的核心在於控制編譯相依與保護命名空間純淨。前置宣告、內聯節制、參數順序、包含順序,皆是為了讓大型專案的建置系統保持高效、穩定、可預測。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved