2012-08-14 59 views
5

我知道全局變量很差,應該儘可能避免。但是,在編寫與MPI並行的程序時,有些變量只會被初始化一次,並且永遠不會改變(這個任務的數量,任務的總數等)。將這些變量作爲全球變量仍被認爲是不好的做法?因爲你幾乎都需要訪問這些變量,所以在main中爲它們創建一個類似乎很愚蠢,並且將一個指針傳遞給程序中所有函數的99%。到目前爲止,我的方法是將它們隱藏在名稱空間mpi_glob中(對於C++,我想我不會將它們放在C中的結構中以模擬名稱空間)。我想這個問題也適用於其他只設置一次的變量,比如單位系統等。全局變量和MPI

回答

5

全局變量「不好」的原因是它們引入了單獨的源文件之間的耦合,這些文件很難識別和跟蹤。特別是,如果一個全局變量在程序中的某個位置出現意外狀態,可能很難找出它被修改的位置。

將全局變量替換爲通過引用傳遞給程序中的每個函數的局部變量並不能消除該問題。在設計方面,它是「流氓數據」,即即使在不需要它的地方四處漫遊的數據。

現在,這裏的意義在於,正如您所建議的那樣,初始化一次且永不改變的數據不會導致全局變量「不良」的問題。由於問題不存在,因此不需要解決方案。

0

沒有規則應該通過懸崖來遵循,具體完全取決於您正在編寫什麼類型的程序。

如果你的程序相對較小(或者你是唯一編寫/維護它的程序),那麼將「全局」變量保留在一個特殊的命名空間中可能沒有問題。至少你不可能在某個地方的某個地方範圍內意外地隱藏或跺跺它們。這是假設你沒有做這樣的事情,雖然:

using namespace mpi_glob; 

這與只是有一個文件中的全局變量的地方有點不同,不保護他們非常喜歡。

如果通過使用全局變量使程序更清晰易懂,然後使用它們。如果可以將它們保持在本地,則將它們保持在本地,因爲從長遠來看,它通常會使維護變得更簡單。

0

我想Singleton應該可以幫助你更好地管理它,所以你不必傳遞指針。實際上,mpi_glob也是一樣,Singleton只是更習慣的方式。

或者,你仍然可以求助於全局變量 - 它們並不是壞的。如果你想強調一次分配就可以宣佈他們const,並通過靜態初始化像這樣設置它們:

const int number_of_tasks = get_preconfigured_number_of_tasks(); 

如果你的全局變量用來保存編譯時間常數,那麼它是完美的罰款,以取代他們與enum成員或預處理器定義。這樣做會減輕編譯器的負擔,因爲它可以在沒有內存訪問的情況下就地使用即時值。


值得信賴的皮特貝克爾指出單身人士問題在他的評論。如果這些問題也打擾你,那麼可以採取完全不同的方法。

還記得Java程序是如何實現的嗎? main方法和所有程序的工作都是從主要方法內部運行的。 Main仍然是成員函數,即它可以獨佔訪問主類的一些私有字段(在Java的情況下它們必須是靜態的,但這不是這裏的要點)。

我們可以進一步將概念延伸到Command這樣的實現。與傳統Java的不同之處在於,您的主要方法等價物不是靜態的,您的具有特定於包含程序的值的全局變量是非靜態成員變量。所有需要訪問全局狀態數據的函數都將被轉換爲成員函數。這是可能的,因爲main方法也是成員函數。

這樣,我認爲,你可以實現更好的封裝和數據安全。

+1

一個單例對於常量來說是矯枉過正的,並且只會給全局數據提供一個安全的幻覺。全局數據的問題在於,它可以從任何源文件進行修改,因此很難看到進行特定更改的位置。使它成爲單身並不會改變這一點。我知道使用單例的唯一好處是它減少了初始化問題的順序。但是初始化問題的順序來自過度使用全局變量;減少全局使用也可以減少這些問題,並減少全局性出現的調試問題。 – 2012-08-14 12:19:54

+0

@PeteBecker我同意你關於數據控制,特別是如果單身人士只是一個愚蠢的對象沒有getter/setters。在這種情況下,Singleton並不意味着帶來OP沒有要求的優勢。我已經繪製它只是代表更普通的方式,像我這樣的普通程序員會期望。對於常量來說,這當然是一種矯枉過正,這就是爲什麼還有其他選擇。 – 2012-08-14 12:32:22

+0

無論你從一個單身人士獲得的物品是否有getter和setter。它仍然是全球數據。吸收者和制定者沒有什麼用處,也沒有用純粹的全球數據那樣有用。 – 2012-08-14 13:10:44