大型專案開發: 標頭檔案順序
經驗告訴我們,某些編碼實踐雖然在C++中完全合法,但是絕對不能應用於大型專案環境中。 大型專案環境下必須有適當的約束,否則很容易變得難以控制並很難維護(摘自<<大規模C++程式設計>>)。下面以Chromium中運用的兩個Coding Style中定義的標頭檔案順序為例。
標頭檔案順序的差異
WebKit/Blink遵循業界標準的定義,其實也是Lakos在<<大規模C++程式設計>>中建議的順序 :
- 編譯單元對應的標頭檔案 (Related header file)。
- 工程內的其它標頭檔案。
- 庫及系統標頭檔案。
(Blink特殊的一點是編譯單元必須先包含config.h。)
這樣做的目的是為避免隱性依賴。每個標頭檔案都應當做到自包含(Self-Contained, or Self Sufficient), 這樣保證使用者能直接標頭檔案中理解它的物理依賴。如果遵循這個順序,當出現隱性依賴時,是無法編譯通過的。
下面這個例子:
my_class.h中依賴了std::string, 但沒有顯式的包含,當main裡先包含標準庫的標頭檔案string時,編譯是不會出錯的。
main.cc
#include <string>
#include <iostream>
#include "my_class.h"
int main(int argc, char* argv[]) {
MyClass aInstance;
std::cout << aInstance.value() << std::endl;
}
my_class.h
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
class MyClass {
public:
MyClass();
const std::string& value();
private:
std::string value_;
};
#endif
如果遵循上面的規則,就會在編譯main.cc時報錯:
In file included from main.cc:1:
./my_class.h:6:9: error: use of undeclared identifier 'std'
const std::string& value();
在一個層次更為清晰的專案下,錯誤最好歸屬到作者身上。這裡main.cc做為my_class.h的使用者,這樣的錯誤最好由my_class.h的作者來解決。所以Google定義瞭如下的規則:
• 關聯的標頭檔案
• C庫標頭檔案
• C++庫標頭檔案
• 其它庫標頭檔案 * 專案中的其它標頭檔案。
實現如下的my_class.cc時就會收到報錯: my_class.cc
#include "my_class.h"
#include <string>
MyClass::MyClass()
:value_("Hello!") {
}
在這種情況下,這個錯誤將只報給my_class.h對應的編譯單元my_class.cc。
In file included from my_class.cc:1:
./my_class.h:6:9: error: use of undeclared identifier 'std'
const std::string& value();
如果是一個小專案,可能察覺不到這樣做的差異。但在講求職責清晰,分工協作的大型專案下,它就會變得很有價值。
這是一個很小的點,可見大型專案中一些規則定義的冰山一角。再比如大型專案中的標頭檔案還有一些設計上的權衡。比如避免不必要包含標頭檔案會拖慢專案的構建效率,引入了前置宣告。但它卻在一些場景下會造成歧義(比如前置宣告標準庫中的類,或者模板類),或者引入一些的維護成本和風險(比如函式的引數變化,需要對應修改前置宣告)。Google早期是鼓勵使用前置宣告,而現在只是強調在明確帶來好處的情況下才建議使用前置宣告。
擴充套件閱讀:
Self-sufficient header files in C/C++
Headers and Includes: Why and How
C/C++ include file order/best practices
相關文章
- iOS開發·專職協議宣告的標頭檔案iOS協議
- SpringBoot配置檔案優先順序載入順序Spring Boot
- 8.13 標頭檔案剖析:標頭檔案路徑(下)
- locate標頭檔案和庫檔案
- [springboot]配置檔案載入順序Spring Boot
- 報錯:Qt 開啟專案找不到Qt自己的標頭檔案QT
- 標頭檔案講解
- 祖傳標頭檔案
- 一款免費使用的PDF檔案批次合併工具,可操作pdf檔案順序,按順序合併pdf檔案。
- 一款免費使用的PDF檔案批量合併工具,可操作pdf檔案順序,按順序合併pdf檔案。
- C 語言專案中標頭檔案包含的最佳實踐
- vscode新建cmake專案ctrl左鍵無法索引標頭檔案VSCode索引
- 標頭檔案的作用分析
- 什麼是 標頭檔案
- 02@在類的標頭檔案中儘量少引入其他標頭檔案
- C/C++標頭檔案太難記?一個萬能標頭檔案全搞定!C++
- linux下使用windows標頭檔案LinuxWindows
- C語言 - 標頭檔案包含C語言
- c++筆記_標頭檔案C++筆記
- VScode開發ROS 解決ros找不到標頭檔案等問題VSCodeROS
- PMO兩大要務:專案選擇與優先順序排序,助力專案成功排序
- 一行命令為專案檔案新增開源協議頭協議
- mpvue開發大型體育專案及總結記Vue
- 如何在大型專案中使用Git子模組開發Git
- 巨集_變數_函式_指標_標頭檔案變數函式指標
- python大型專案開發規範_學習Python模組匯入機制與大型專案的規範Python
- python中按照資料夾中檔案的排列順序讀取檔案內容Python
- 關於C++的標頭檔案C++
- 8.10 標頭檔案剖析:變數宣告變數
- 8.11 標頭檔案剖析:前向引用
- 8.14 Linux核心中的標頭檔案Linux
- 8.8 標頭檔案剖析:基本概念
- C/C++標頭檔案一覽C++
- 看標頭檔案猜演算法演算法
- pycharm設定python標頭檔案模版PyCharmPython
- Oracle RAC 環境 引數檔案的啟動順序Oracle
- 檔案隨機或順序讀寫原理深入淺出隨機
- 在大型專案開發上,Python 真是個“爛”語言!Python
- 在大型專案開發上,Python真是個“爛”語言!Python