大型專案開發: 標頭檔案順序
經驗告訴我們,某些編碼實踐雖然在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
相關文章
- C++ 標頭檔案的包含順序研究C++
- iOS開發·專職協議宣告的標頭檔案iOS協議
- 大型專案開發:謹慎使用智慧指標指標
- struts檔案配置順序
- 8.13 標頭檔案剖析:標頭檔案路徑(下)
- C 標頭檔案
- 報錯:Qt 開啟專案找不到Qt自己的標頭檔案QT
- locate標頭檔案和庫檔案
- SpringBoot配置檔案優先順序載入順序Spring Boot
- 臨時檔案的順序和絕對檔案號
- #include sys/xxx.h標頭檔案 UNIX標頭檔案
- IDEA下JNI開發快速生成標頭檔案方法Idea
- C 標頭檔案 作用
- 祖傳標頭檔案
- 標頭檔案講解
- 一款免費使用的PDF檔案批次合併工具,可操作pdf檔案順序,按順序合併pdf檔案。
- 一款免費使用的PDF檔案批量合併工具,可操作pdf檔案順序,按順序合併pdf檔案。
- C 語言專案中標頭檔案包含的最佳實踐
- 標頭檔案的作用分析
- fcntl.h標頭檔案
- linux 標頭檔案 作用Linux
- 什麼是 標頭檔案
- web.xml 檔案 配置載入順序WebXML
- [springboot]配置檔案載入順序Spring Boot
- 標頭檔案與庫檔案與菜鳥 (轉)
- 02@在類的標頭檔案中儘量少引入其他標頭檔案
- react-native大型專案開發實踐React
- 開發維護大型 Java 專案的建議Java
- C語言rewind()函式:將檔案指標重新指向檔案開頭C語言函式指標
- C/C++標頭檔案太難記?一個萬能標頭檔案全搞定!C++
- WordPress工作原理之程式檔案執行順序
- Windows XP 指定啟動專案的順序(轉)Windows
- c++筆記_標頭檔案C++筆記
- Nt函式原型標頭檔案函式原型
- C語言 - 標頭檔案包含C語言
- C++ 中神奇的標頭檔案,懶人專用C++
- vscode新建cmake專案ctrl左鍵無法索引標頭檔案VSCode索引
- mpvue開發大型體育專案及總結記Vue