12. 規則特例

前面說明的程式撰寫慣例基本上都是強制性的。但和所有優秀的規則一樣,免不了都有例外,我們將在此探討。

12.1. 現有不合規範的程式碼

小訣竅

若是現有的程式碼不符合這些撰寫風格,可以網開一面。

如果你發現正在修改的程式碼使用其他的撰寫風格時,為了與程式碼原有風格保持一致,可以不用死守本指南。如果不知該如何處理較好,可以和程式碼原作者或現在的負責人員討論。請記住, 一致性 原則包括「和原有的程式保持一致性」。

12.2. Windows 程式碼

小訣竅

Windows 開發者已有一套自己的程式撰寫習慣,主要源於 Windows 標頭檔和其它來自 Microsoft 的程式碼。我們希望任何人都可以順利讀懂你的程式碼,所以針對所有平台的 C++ 程式撰寫風格只給出一個單獨的指南。

如果你習慣使用常見的 Windows 撰寫風格,在此有必要重申某些你可能會忘記的規則:

  • 不要使用匈牙利命名法(比如把整數變數命名成 iNum)。請使用 Google 命名規則,包括使用 .cc 做為 C++ 程式碼檔案的副檔名。

  • Windows 為原生型別定義了很多專屬的同義型別,如 DWORDHANDLE 等等。在呼叫 Windows API 時這是完全可以接受的,我們甚至鼓勵這麼做。但還是請儘量使用原有的 C++ 型別。例如:不要使用 LPCTSTR,改用 const TCHAR *

  • 使用 Microsoft Visual C++ 進行編譯時,將警告等級設置為 3 或更高,並將所有的 warnings 當作 errors 處理。

  • 不要使用 #pragma once;請使用 Google 規定的 include 保護規則。Include 保護的路徑應該相對於專案根目錄。

  • 事實上,除非萬不得已,不要使用任何非標準的延伸功能,例如 #pragma__declspec。允許使用 __declspec(dllimport)__declspec(dllexport);但你必須透過巨集(像是 DLLIMPORTDLLEXPORT)來使用,這樣其他人在共用使用這些程式碼時,可以很容易將這些延伸功能關閉。

不過,在 Windows 上,在少數一些情境下,我們可以偶爾違反規則:

  • 通常我們 不允許使用多重繼承;然而,在使用 COM 和某些 ATL/WTL 類別時,多重繼承是不可或缺的。為了實作 COM 或 ATL/WTL 的類別和介面,你可以使用多重實作繼承。

  • 雖然程式碼中不應該異常處理,但是 ATL 和部分 STL(包括 Visual C++ 提供的版本)卻大量使用異常處理。使用 ATL 時,你應該要定義 _ATL_NO_EXCEPTIONS 以關閉異常處理。你應該要研究一下是否能夠關閉 STL 的異常處理,如果沒有辦法,可以在編譯器設定中讓異常處理維持開啟。(請注意:這只是為了讓 STL 能通常編譯。你自己撰寫的程式碼仍然不允許使用異常處理。)

  • 為了使用標頭檔預編譯 (precompiled headers) 的功能,一般做法是在每個 .cc 檔案的開頭引入一個特定的檔頭檔,通常檔名是 StdAfx.hprecompile.h。為了使程式碼方便與其他專案共用,避免明確地引入這個檔案(但 precompile.cc 除外),然後利用 /FI 選項通知編譯器自動引入。

  • 資源 (resource) 標頭檔通常命名為 resource.h 且只包含巨集,不需要遵守本風格指南。