簡體   English   中英

.cpp 文件和 .h 文件有什么區別?

[英]What is the difference between a .cpp file and a .h file?

因為我已經制作了 .cpp 文件,然后將它們傳輸到 .h 文件中,所以我能找到的唯一區別是你不能 #include .cpp 文件。 我缺少什么區別嗎?

C++ 構建系統(編譯器)不知道有什么區別,所以它都是一種約定。

約定是 .h 文件是聲明,而 .cpp 文件是定義。

這就是 .h 文件被 #included 的原因——我們包括聲明。

.cpp 文件是編譯單元:它是將被編譯的真正源代碼文件(在 C++ 中)。

.h(頭文件)文件是將被虛擬復制/粘貼到 #include 預編譯器指令出現的 .cpp 文件中的文件。 一旦將頭代碼插入到 .cpp 代碼中,就可以開始編譯 .cpp。

標頭( .h.hpp 、 ...)文件包含

  • 類定義( class X { ... };
  • 內聯函數定義( inline int get_cpus() { ... }
  • 函數聲明( void help();
  • 對象聲明( extern int debug_enabled;

源文件( .c.cpp.cxx )包含

  • 函數定義( void help() { ... }void X::f() { ... }
  • 對象定義( int debug_enabled = 1;

但是,頭文件以.h后綴命名而源文件以.cpp后綴命名的約定並不是真正需要的。 人們總是可以告訴一個好的編譯器如何處理某個文件,而不管它的文件名后綴( -x <file-type> for gcc. Like -x c++ )。

源文件將包含在整個程序中只能出現一次的定義。 因此,如果您在某處包含一個源文件,然后將該文件的編譯結果與源文件本身鏈接在一起,那么您當然會得到鏈接器錯誤,因為這些定義現在出現了兩次:一次在包含源文件,然后在包含它的文件中。 這就是您在包含.cpp文件時遇到問題的原因。

.h 文件或頭文件用於列出類聲明中可公開訪問的實例變量和方法。 .cpp 文件或實現文件用於實際實現這些方法並使用這些實例變量。

它們分開的原因是因為 .h 文件沒有被編譯成二進制代碼,而 .cpp 文件是。 以圖書館為例。 假設您是作者並且您不希望它是開源的。 因此,您將編譯后的二進制庫和頭文件分發給您的客戶。 這使他們可以輕松查看有關他們可以使用的庫類的所有信息,而無法查看您是如何實現這些方法的。 它們更適合使用您的代碼而不是編譯器的人。 正如之前所說:這是慣例。

我知道聲明和定義之間的區別。

然而:

  • CPP 文件包括它所包含的任何頭文件的定義(因為 CPP 和頭文件一起成為一個“翻譯單元”)
  • 一個頭文件可能包含在多個 CPP 文件中
  • 鏈接器通常不會喜歡在多個 CPP 文件中定義的任何內容

因此,頭文件中的任何定義都應該是內聯的或靜態的。 頭文件還包含被多個 CPP 文件使用的聲明。

既非靜態也非內聯的定義放在 CPP 文件中。 此外,僅在一個 CPP 文件中需要的任何聲明通常放置在該 CPP 文件本身中,而不是任何(可共享的)頭文件中。

一個好的經驗法則是“.h 文件應該有[可能] 被多個源文件使用的聲明,但沒有可以運行的代碼。”

其他人已經提供了很好的解釋,但我認為我應該澄清各種擴展之間的區別:

Source Files for C: .c
  Header Files for C: .h

  Source Files for C++: .cpp
  Header Files for C++: .hpp

當然,正如已經指出的那樣,這些只是慣例。 編譯器實際上並不關心它們——這純粹是為了編碼器的利益。

按照慣例,.h 文件會被其他文件包含,並且不會被它們自己直接編譯。 .cpp 文件 - 再次,按照慣例 - 編譯過程的根源; 它們直接或間接包含 .h 文件,但通常不包含 .cpp 文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM