2011-08-26 26 views
2

我正在開發一個小型軟件項目,我希望將來能夠以開放源代碼的形式發佈這個項目,所以我希望收集有關這個問題目前被接受的最佳做法的意見。在單個頭文件或各自頭文件中定義全局變量(extern)會更好嗎?

應用程序本身是程序性的,面向對象(也沒有必要對我來說,封裝在一個類中的渲染功能或事件處理函數),但某些方面的應用很大程度上是面向對象的(比如嚴重依賴OO的腳本控制檯)。代碼的OO方面具有標準object.cppobject.h文件。

對於程序部分,我將代碼拆分爲各種文件(例如main.cpp,render.cpp,events.cpp),每個文件可能都有一些特定於該文件的全局變量。我也有相應的頭文件,定義了我想要從其他文件訪問的所有函數和變量(如extern)。然後,當我需要從另一個源文件訪問該函數/變量時,我只需要#include正確的頭文件。

我今天意識到我還可以有其他選擇:創建一個單獨的globals.h頭文件,我可以在其中定義所有全局變量(如extern),以及在特定源文件之外需要的函數。然後,我可以在所有源文件中使用這個文件(而不是像我現在這樣做的每個單獨的頭文件)。此外,使用這種方法,如果我需要將變量/函數推廣到全局(而不是本地),我可以將條目添加到頭文件中。


問題:它是一個更好的做法是使用一個相應的頭文件爲每一個.cpp文件(並定義變量/函數我想在這些頭全局訪問),或者使用單頭文件來聲明所有全局可訪問的變量/函數?


另一種快速的更新,在全局的(但不是所有)被用作這樣的,因爲我的應用程序是多線程的。

+1

爲什麼標記爲「C」?決定一種語言。如果這是C++,「所有全局變量」必然引發一些反應。 –

+0

我使用C++創建了程序,但它具有綁定到Lua和SDL(它們都用C編寫)。我也希望將這種做法擴展到我爲嵌入式系統編寫的另一個應用程序(C語言)。程序的主要流程是程序化的(沒有單例對象),所以我確實需要全局變量。 – Breakthrough

+0

只需將'globals.h'中的所有全局變量聲明爲** extern **就不會給出它的定義。您應該至少在一個源文件中定義它們。否則,連接器會對** extern **變量的使用情況進行投訴。 – Mahesh

回答

3

對我來說,有一個對應於每個實現(c或cpp)文件的頭文件是更好的方法。你必須將你的類,結構和函數看作模塊,並且如果你分解了你的實現,那麼分解你的錯誤也是合乎邏輯的。

另一件事是,當您修改頭文件時,它會導致包含它的所有文件在構建時重新編譯。最後,我可以告訴你,這可能需要很長時間。您可以通過正確分割您的聲明來避免重建所有內容。

+0

+1,但讓我們說我刪除'x.cpp'中使用的全局,但是'y.cpp'中的** not **。編譯器是否不會意識到'y.cpp'沒有什麼改變,並且避免重新編譯目標文件,或者編譯器是否依賴原始的源代碼修改(因爲實質上,'#include'頭只是轉儲原始代碼在那裏)? – Breakthrough

+0

@破解:編譯器沒有意識到沒有任何東西改變爲'y.cpp',因爲它從不會看到_just_'y.cpp'。它看到'globals.h' +'y.cpp',因爲它們已經被預處理器放在一起了。對編譯器來說,對'globals.h'的更改看起來像是對包含'globals.h'的_every_文件的更改,因此是重新編譯。 –

2

我會建議有更多的標題,並減少它們。你必須擁有一系列的內容,但如果它錯了,那麼它就很容易理解和編輯。

有一個大的全局變量很難應付,如果有些事情變得古怪。如果你確實需要改變某些東西,那麼這種改變潛在的影響就很大,而且風險很大。

在這種情況下,更多的代碼並不是一件壞事。

一個小問題是,由於每個文件都必須處理它,因此您的編譯時間將超過線性增加,因此放置在那個大標題中的次數越多。在一個嵌入式項目中,這可能不是一個擔心,但總體而言,標題中的大量內容會讓你失望。

+0

+1,感謝Tom的迴應......非常感謝。這個答案和一個@Shlublu發佈的答案一樣有效,但他回答得更快,所以我不得不接受他的答案。 – Breakthrough

1

最好把它們全部放在一個文件中並且根本不編譯該文件。如果你有全局變量,你應該重新考慮你的設計,特別是如果你正在做應用程序編程而不是低級系統編程。

+0

你的意思是「根本不編譯該文件」?或者你只是意味着一個頭(因爲頭沒有在技術上編譯)... – Breakthrough

+0

這是一個迂迴的方式說「擺脫你的全局變量」 –

0

正如我在下面的問題的評論中所說的,首先要做的是嘗試並消除所有全局數據。如果這是不可能的,而不是一個大的頭,或者把每個課堂的頭部都放到外面,我會採用第三種方法。

假設你的Event類需要一個全局實例。如果您在event.cpp中聲明瞭全局實例並在event.hpp中聲明瞭外部實例,那麼這基本上使這些文件在其他任何地方都不可重用。將它投入globals.cppglobals.hpp並不理想,因爲每次全局標題被修改時,您的整個項目都將被重建,因爲標題被所有人包括在內。

所以第三種方法是爲每個需要全局實例的類創建一個伴隨的頭文件和源文件。因此,您將在event_g.cpp中聲明Event全局實例,並在event_g.hpp中聲明該實例。

是的,它是醜陋的,是的,它是單調乏味的。但是,全球數據並沒有什麼好處。

相關問題