2009-12-19 39 views
1

我發現了一些解釋爲什麼C++分離.cpp和.h文件的線程(例如here)。我有興趣知道它是否會導致任何問題,如果我不要將它們分開。我不想共享目標文件,那麼在一個小型項目中分離的好處是什麼?如果它只是減慢編譯時間,在我看來這不是什麼大問題。我想用C++重新實現一個Java程序,所以對於我來說,只將一個類保存在一個文件中似乎更容易。例如:如果只使用沒有單獨頭文件的cpp文件,有什麼缺點?

// Hello.cpp 
#ifndef HELLO_20091218 
#define HELLO_20091218 

#include <iostream> 
#include "Utils.cpp" 

class Hello 
{ 
public: 
    void start() 
    { 
     std::cout << Utils::nrand(100) << "\n"; 
     // Utils and all other classes are written in a similar way 
    } 
}; 

#endif 

有一件事困擾着我。 「在類中定義一個成員函數會要求實現將調用擴展爲內聯。」因此,如果我喜歡這樣做,所有內容都會隱式標記爲內聯。它會導致更大的可執行文件或其他缺點?

+0

非常相似:http://stackoverflow.com/questions/1686204/help-a-c-newbie-understand-his-mistakes-header-files-and-cpp-files第一個答案也回答你的問題。如果不是,請考慮編輯此問題。 – cbrulak

+0

部分地回答我的問題:我遇到了一種情況,即分離是**必須**,即兩個類之間的循環依賴。更多信息在這裏:http://stackoverflow.com/questions/2089056/cyclic-dependency-between-header-files。 – Jabba

+0

*相關:* [我怎樣才能避免包括類實現文件?](http://stackoverflow.com/q/2037880/54262) – 2010-10-31 07:38:35

回答

3

在C和C++中,編譯的最小單位是文件。如果您只是不使用頭文件並將所有內容包含在「主」文件中,則每次更改某些內容時,都必須重新編譯整個程序。對於較大的應用程序來說,這可能是分離標題和實現的非常好的參數。此外,如果您的應用程序的另一部分將存在於另一個二進制可執行文件中,並且您不想重複使用類,那麼您可以使用頭文件進行安全處理,而如果沒有它們,您將獲得大量開銷

如果你不關心這些事情(你會後悔的。)沒有必要爲你分開的頭文件。

關於內聯:無論如何,編譯器會內聯許多函數(有時甚至是整個類,可以這麼說),即使你不要求它這樣做。內聯通常對性能有益。有些角落案例(可執行文件的大尺寸可以在較慢的執行過程中解決),但這些情況相當不尋常。

3

這確實是兩個問題。

現在,您在上面顯示爲「Hello.cpp」的內容看起來像一個頭部,並且包含一個包含後衛。編譯器並不在乎你給頭的名字是什麼,但是包含一個.cpp文件將會讓任何人看到你的代碼時感到困惑。如果你自己編寫這個程序,那麼包含守衛(至少)應該可能會去 - 雖然它不會造成真正的問題,但最好是毫無意義和困惑。

是的,您在類定義中定義的成員函數是隱式內聯的。這並不意味着編譯器需要爲它們生成內聯代碼。這基本上只是編譯器的一個暗示,大多數編譯器都決定是否生成內聯代碼,主要基於函數包含的內容,而不是它定義的位置。

+1

也見'#include「Utils.cpp」,這肯定表明這是案子。 –

+0

它不僅僅是一個標題,因爲它也包含了函數的定義。我的想法是定義一個類中的所有方法(比如在Java中)。 – Jabba

+0

你可以這樣做,但標準做法是調用文件「Hello.h」,而不是「Hello.cpp」。如果你從其他文件中包含它,那麼它就是一個標題,不管它定義了什麼。調用一個文件「* .cpp」告訴其他人你將把它編譯爲「頂級」源文件。 –

2

頭文件的目的是封裝應用程序視爲的一個特定的功能,如API

在很多情況下,相應的源文件位於單個庫文件中,或者至少是一個獨立的包。直接結合的源代碼(如單獨的文件)到項目是權宜之計,經常有幫助的發展,而不是建立一個圖書館和連接該英寸

這詞,如API是如此重載以及其他技術含義證明了開發者對這種安排的重視。

如果你認爲這是爲你寫一類的一些未來的重用,它不會是不好的做法,打破成獨立.cpp.h文件,這樣就可以很容易地引用它的另一個項目。至於編輯速度的處罰,考慮長期收益與成本。 (並且編譯器和硬件每年都會變得更快)。

1

「當在羅馬入鄉隨俗做」

你被欺騙,你有一個選擇使用C++和Java一樣的思維。雖然這在技術上是正確的,但你打破了一些非常強大的約定存在的原因。您可以輕鬆開始使用新的程序,而無需調用delete,因爲「這不是什麼大問題」,或者「程序很小」或「操作系統將在程序關閉後收回所有內存」,但這並不意味着您應該這樣做。我同意C++比Java更復雜,這可能是一個真正的痛苦,但這是你必須處理的。這是每個C++開發人員遲早會接受的。

相關問題