2010-04-01 53 views
2

對我來說,我通常會讓所有成員都成爲靜態的全球課程。所有其他類將繼承此全局類。在C++中使用全局變量的最佳方式是什麼?

我想知道這是否是一種好的做法?

有人有什麼建議嗎?

+5

爲什麼要使用全局變量? – 2010-04-01 19:54:38

+0

如果所有成員都是靜態的,並且該類可以在全局訪問,那麼爲什麼您需要從它繼承?如果該字段是公共的,您可以使用Namspace :: ClassName :: MemberName訪問這些字段。 – 2010-04-01 20:04:33

+3

@Steve:關於這個問題的可怕之處在於,我可以把它寫成愚人節玩笑話,儘管我會努力工作至少一個額外的壞主意。 – 2010-04-01 20:11:08

回答

6

通常儘量避免全局變量,因爲它們引入全局狀態。與全球國家,你沒有referential transparency。引用透明度是一件好事,全球狀況是一件壞事。例如,全局狀態使得單元測試毫無意義。

雖然你必須,但我同意大多數時候你提到的方法是好的。您還可以在任何.cpp文件中聲明全局變量,然後在.h文件中爲該全局變量指定一個外部變量。

+0

難道你不想要一個全局狀態,例如,在一個調試類或一組調試功能中,允許隨着時間的推移輸出到中央窗口或控制檯。有些東西很難調試,比如具有關鍵部分的線程...... – Eric 2011-01-26 21:01:04

0

Ick!

全局變量是一個全局變量。重命名它 - 即使名稱使其看起來像一個可變成員,也不會改變它。每個問題你有一個oridinary全局變量,你仍然會用你的全局變量作爲通用靜態成員方案(可能還有一些新的方案)。

1

最好的方法?仔細地...... :-)

1

您的建議做法尚未解決與全局變量相關的單個問題。

  • 具有訪問功能的私有成員數據允許單點控制讀/寫和驗證,提高健壯性,可維護性和易於調試。
  • 使數據成員靜態只會降低靈活性;您可能需要包含相同數據結構的多個獨立全局對象。如果應該只有一個,請使用單例模式。
  • 將不相關的全局數據收集到一個類中打破了有關耦合和內聚的最佳實踐,而且幾乎不是OO。

This article與C和嵌入式系統有關,但與您的問題無關。

1

首先,全局狀態不好。由於任何部分的行爲都可能取決於全局變量,這使得對該程序的理解變得非常複雜。這使得它更難以測試。它提供了一種方式,通過這種方式,兩個遠程函數可以創建一個不一致的狀態,從而可能會混淆另一個函數,而調試起來確實非常困難。

全球國家的性質並不重要。例如,這通常是關於Singleton模式的惡意代碼。

但是,讓每個類都從一個全局變量類繼承是一個壞主意。在C++中,應該謹慎使用繼承,因爲它在實現中將兩個類聯繫在一起。讓所有類以任何形式從一個基類繼承,並且C++不能很好地處理多重繼承通常是一件壞事。獲得「致命的鑽石」效果將非常容易,因爲如果A從B繼承並且它們都從Global繼承,Global將在A的繼承層次結構中出現兩次。

-1

您很可能正在尋找Singleton模式。這並不是說所有的全局變量都需要使用該模式。但是,當我擁有一個全局的時候,通常是因爲我只想爲整個程序實例化一個實例。在這種情況下,單身人士可以很好地工作。

http://en.wikipedia.org/wiki/Singleton_pattern

+1

如果您只需要一個實例化,那麼只能進行一個實例化。無需過度複雜的事情。 http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/ – GManNickG 2010-04-01 20:15:15

1

有兩件事情是懊惱我:使用全局變量是不好的,但有時很難不這樣做,但是我對懊惱:

  • 繼承的明確濫用
  • 美妙的依賴問題

兩者的結合有着驚人的效果。

比方說,我創建將訪問一個全局變量的一類,從你的反模式它提供了:

#include "globals.h" 

class MyClass: Globals // for my own sake I assume it's not public inheritance 
{ 
}; 

當然,#include是在頭強制性的,因爲我是從它繼承。因此,每次我添加/更改一個全局變量,即使是單個類使用的變量,我也會重新編譯整個應用程序。

如果我們曾經在同一個團隊工作過,那會給你一個非常苛刻的,非常嚴厲的評論......至少可以說。

相關問題