2017-06-01 169 views
0

如果您在類中聲明瞭一個公共變量,那麼您可以從任何也是該類成員的函數修改該變量。C++公共變量範圍混淆

如果你在一個函數中聲明瞭一個變量,那麼它的範圍不會超出函數的範圍。

那麼是一個公共類變量本質上是一個全局變量,可以被任何類的成員訪問和更改?

如果是這樣的話,全局變量和公共變量有什麼區別?

+0

全局變量無處不在,無論如何。一個公共變量只能通過你的類的一個實例訪問。 – FrenchMajesty

+1

@FrenchMajesty「全局變量在任何地方都可以訪問,不管是什麼」,只有當它們是外部的,否則它們都被限制在文件範圍內。 – George

+0

@George:編譯器不知道,所以它必須將任何非靜態文件作用域變量視爲全局對象。 – MSalters

回答

2

如果您在類中聲明瞭一個公共變量,那麼您可以從任何也是該類成員的函數中修改該變量。

不完全一樣:這同樣適用於私有和受保護的變量。也就是說,如果一個班級有3個變量,其中一個是public,一個是protected,另一個是private,那麼該類別的成員的功能不僅可以修改公共的一個;相反,他們可以修改所有3.作爲同一類的成員給你最高的權限。當試圖操作以外的那些變量時,可以看到這3個訪問修飾符之間的區別:公共變量可以從任何地方訪問,受保護的變量可以從同一個類和從它派生的類訪問(如果有的話) ,而私人的只能從同一班級的其他成員中獲得。

如果你在一個函數中聲明瞭一個變量,那麼它的作用域不會超出該函數的範圍。

是的,實際上也適用於任何塊:如果在for循環內聲明變量,其範圍將爲循環。函數只是一種塊。

那麼,公共類變量本質上是一個全局變量,可以被任何類的成員訪問和更改嗎?

不,正如我上面一個公共類變量可以通過成員的任何類,甚至從一些不屬於任何類訪問說:這正是「公共」的含義。

如果是這樣的話,全局變量和公共變量有什麼區別?

由於CoryKramer在his answer說,一類成員生活的目標內部,對象是相互獨立的,因此,如果您創建相同類的10個對象,所有10個都會有自己該變量的副本。 static類成員是一個例外,因爲它們由類的所有對象共享,實際上甚至不需要單個對象存在(您是否熟悉Singleton的概念?如果沒有靜態成員,它將無法工作)。

一個實際的區別:假設您想將文件的名稱存儲在一個可以從您的所有函數輕鬆訪問的位置。全球都會做。相反,一個類的公共成員要求您先創建該類的對象,然後該對象必須在範圍內!如果在main()中創建對象,然後想從名爲write_results_to_file()的函數中讀取該變量,以便知道要寫入哪個文件,則必須注意將該對象傳遞給該函數,否則該對象將不在儘管公開,範圍和公衆成員將無法到達。

因此,全局變量更加方便,因爲它們需要較少的工作。這正是人們喜歡使用它們的原因,但請注意,這種懶惰帶來了糟糕的代碼:如果使用全局變量,編寫代碼更容易,但是很難理解每個函數的工作方式。理想情況下,函數只需要它的參數,然後就可以運行併產生結果。在C++中,通常可以通過查看.hh文件中的聲明來查看函數的參數。但是如果函數訪問一個全局變量,我們可以說該函數使用了一個「隱藏」參數,其中「隱藏」意味着它不在其聲明中顯示。一旦程序增長到一個不平凡的大小,這實際上使事情變得更加困難,因爲很難理解變化的後果。例如,如果程序修改了一個全局變量,那麼所有使用該變量的函數都會受到影響,但在某些情況下,它將不會顯而易見,這會導致難以發現的細微錯誤。再舉一個例子,測試一個函數可能會變得更加困難:如果你編寫了一些測試用例,只要你傳遞的參數是相同的,你會期望只要你運行它們,你就會得到相同的結果。相反,結果將取決於參數(這是清楚的),也取決於全局變量的值(這不明顯)。這就是爲什麼全局變量不受歡迎的原因:因爲它們使編寫代碼變得簡單快捷,但難以理解並維護它(增加新功能或修復錯誤)。使用它們不是禁止的,但你應該謹慎而謹慎地做到這一點。

5

您所缺少的更重要的語義是類成員變量(除非它是static)特定於該類的每個實例。例如

class Foo 
{ 
public: 
    Foo() = default; 
    int x; 
}; 

如果我說

Foo a{}; 
Foo b{}; 

a.x = 1; 
b.x = 7; 

a.x != b.x; // value is different 
&a.x != &b.x // address is different 

注意,成員變量x具有不同的值,具有不同的地址(因爲它是一個完全不同的int),和屬於每個Foo的實例。

現在關於static提,注意,因爲我需要一個Foo的實際實例爲其訪問它的成員變量,我不能做到這一點

Foo::x = 5; // only works if x is static 

。而是一個static成員不需要一個實例,並且整個類都有一個共享該成員的單個實例。