2011-06-21 57 views
21
  • 是否有一些首選的方法來組織包括指令?
  • .cpp文件而不是.h文件包含在需要的文件中是否更好?翻譯單位是否受到某種程度的影響?
  • 如果我在.h文件和.cpp文件中都需要它,我應該將它包含在.h文件中嗎?這很重要嗎?
  • 將已定義的文件保存在預編譯頭文件(stdafx.h)中,例如std和第三方庫,是否是一種很好的做法?我自己的文件如何,我應該在創建它們時將它們包含在stdafx.h文件中?

// myClass.h 
#include <string> 
// ^-------- should I include it here? -------- 

class myClass{ 
    myClass(); 
    ~myClass(); 

    int calculation() 
}; 

// myClass.cpp 
#include "myClass.h" 
#include <string> 
// ^-------- or maybe here? -------- 

[..] 

int myClass::calculation(){ 
    std::string someString = "Hello World"; 
    return someString.length(); 
} 


// stdafx.h 
#include <string.h> 
// ^--------- or perhaps here, and then include stdafx.h everywhere? ------- 
+1

杜佩。這已被問了很多次,他經常只是沒有鏈接正確的一個:http://stackoverflow.com/questions/2762568/cc-include-file-order-best-practices – AJG85

+0

@ AJG85該問題問什麼*命令*包含應該在英寸我不要求命令 - 我問包括應該在哪裏,在哪個文件中。 – Default

回答

25
  1. 您應該在文件的頂部有他們,在同一個地方。這是每個人都期待的。另外,將它們分組是很有用的,例如,首先是所有標準標題,然後是第三方標題(按庫分組),然後是自己的標題。在整個項目中保持這個順序一致。它使得理解依賴關係變得更加容易。正如@James Kanze指出的那樣,首先放置聲明內容的頭部也很有用。通過這種方式,您可以確保它在首先包含的情況下工作(意味着它不依賴於包含它自身的任何包含)。
  2. 保持範圍儘可能小,以便標題中的更改影響最少的翻譯單元數。這意味着,只要有可能,只將它包含在cpp文件中。正如@Pedro d'Aquino所評論的那樣,只要有可能(通常只使用引用或指向給定類型的引用或指針),就可以通過使用前向聲明來減少頭中包含的數量。
  3. 兩者 - 顯式優於隱式。
  4. 經過一番閱讀後,我相信你應該只在PCH中包含標題,如果你確信他們不再改變。這適用於所有標準頭文件以及(可能)第三方庫。對於你自己的圖書館,你是法官。
+0

因此,將它們包含在'.cpp'文件中基本上是爲了避免將它們包含在包含'.h'文件的所有文件中? – Default

+1

@默認:是的。這最大限度地減少了整個項目的依賴性,這有很多原因。 –

+3

+1所有非常好的建議。我的經驗法則是在任何文件(包括.cpp或.h)中包含最少數量的頭文件以使其能夠編譯,這意味着大多數包含在.cpp中,其餘部分包含在.h中。 – vhallac

7

這篇關於Header file include patterns的文章應該對您有所幫助。

  • 是否有一些首選的方法來組織一個include指令?

,您可以在上述文章中找到他們。

  • 是更好地包含您在.cpp文件,而不是 .h文件所需要的文件?某種程度上影響翻譯單位 ?

,最好是有他們在的.cpp。即使在定義另一種類型時需要定義的類型,也可以使用前向聲明。

  • 怎麼樣,如果我需要在這兩個.h文件和.cpp文件,我應該只是 包括在.h文件?它會 重要嗎?

只有在.h文件中,但建議轉發申報的頭文件,幷包含.cpp文件。

  • 它是一個很好的做法,以保持已定義文件在預編譯 頭(stdafx.h中),例如性病 和第三方庫? 我自己的文件如何,我應該將它們包含在 一個stdafx.h文件中,作爲我創建它們的方式? ?

我個人沒有使用預編譯頭,但一直對它們進行討論#2早些時候:

Precompiled Headers? Do we really need them

5

有沒有組織的包括指令一些優選的方法是什麼?

沒有常見的約定。有些人建議按字母順序排列,我個人不喜歡它,並希望保持它們在邏輯上分組。

將.cpp文件而不是.h文件包含在需要的文件中是否更好?

一般來說,是的。它減少了編譯器需要打開並讀取頭文件的次數,以查看那裏的包含守護程序。這可能會縮短整個編譯時間。 有時候也建議在頭文件中儘可能多地聲明類,並且僅將它們包含在.cpp中,原因相同。例如,「Qt人」就是這樣做的。

翻譯單元是否受到某種程度的影響?

在語義上,沒有。

如果我在.h文件和.cpp文件中都需要它,我應該將它包含在.h文件中嗎?這很重要嗎?

只需將其包含在標題中即可。

將已定義的文件保存在預編譯頭文件(stdafx.h)中,例如std和第三方庫是否是一種很好的做法?我自己的文件如何,我應該在創建它們時將它們包含在stdafx.h文件中?

預編譯頭可以顯着減少編譯時間。例如:我的一個項目包括boost::spirit::qi在20秒內編譯PCH,80秒 - 沒有。一般來說,如果你使用一些大量模板填充的庫,如boost,你會想利用PCH的優勢。

至於你的代碼示例中的問題:,因爲你不在標頭中使用std :: string,最好將它包含在.cpp文件中。在stdafx.h中也可以使用#include <string> - 但這隻會增加項目的複雜度,並且幾乎不會注意到任何編譯速度。

1

(4)我不建議將任何額外的文件包含到stdafx.h中。或類似的「include_first.h」文件。直接包含到cpp或特定的h文件中,可以明確地表達代碼的依賴關係,並排除冗餘依賴關係。當您決定將單片代碼分解爲幾個庫或dll時尤其有用。就我個人而言,我使用諸如「include_first.h」(stdafx.h)的文件僅用於配置目的(該文件僅包含當前應用程序配置的宏定義)。
可以通過標記另一個文件來停止預編譯而不是stdafx.h來爲自己的文件提供預編譯頭文件(例如,您可以使用名爲「stop_pch.h」的特殊空文件)。
注意,預編譯的頭可能無法正常對某些種類的預處理器的sofisticated使用的工作(格外,在BOOST_PP_ *使用的一些工藝)

0

這可能是非常重要的發現,類翻譯單位的順序需要是正確的,或者一些C++功能只是被禁用,並導致編譯時錯誤。

編輯:添加例子:

class A { }; 
class B { A a; }; // order of classes need to be correct 
1

從性能上看:

改變任何頭從stdafx.h中會引發新的預編譯包括在內,所以這取決於如何「凍「代碼是。外部庫是stdafx.h包含的典型候選對象,但您當然也可以包含自己的庫 - 這是基於您期望更改它們的頻率的折衷。

而且,與微軟編譯器,你可以在每個頭文件的頂部把這個:

#pragma once 

這使編譯器可以完全跳過第一次出現後的文件,節省I/O操作。傳統的ifndef/define/endif模式需要在每次包含文件時打開和解析文件,這當然需要一些時間。它當然可以積累,並引起注意!

(請務必離開傳統的衛兵在那裏,爲便攜性。)