static根據上下文語意有兩種含義,一種是在類和結構體內,另一種時類在結構體外。
類外的static在鏈結階段是區域性的,它只對它的編譯單元(.obj)可見,而類內的static表示這個變數將在類內與所有例項共享
static.cpp
staticint s_variable=5;
main.cpp
#includeint s_variable=10;int
main()
程式的執行結果是列印10,如果將static.cpp中的static去掉,直接變成int宣告變數s_variable,那麼在鏈結時會報錯,因為s_variable已經在另乙個編譯單元中被定義了,兩個全域性變數的名字不能一樣,改正方法是使用引用
static.cpp
int s_variable=5;
main.cpp
#includeexternints_variable;
intmain()
extern的意思是在另外的編譯單元中尋找定義,也叫外部鏈結,此時執行可以看到列印結果是5。加上static有些類似於在類中宣告私有型別成員,其他的編譯單元(.obj)不能訪問s_variable,函式也是一樣。
static.cpp
voidfunction()
{}
main.cpp
#includeintfunction()
{}int
main()
此時編譯會發生錯誤,因為function被重複定義,如果將static.cpp中的function前面加上static,那麼鏈結將不會出錯。
在標頭檔案中使用靜態變數也是同樣的道理,標頭檔案相當於在引用標頭檔案的位置將標頭檔案的內容複製貼上,因此標頭檔案中使用static定義的靜態變數即使在兩個不同的cpp檔案中被呼叫,也不會引起重複定義,因為它相當於在兩個cpp檔案中各自建立乙個靜態變數,互不干擾。
因此盡量讓全域性變數和函式變成靜態型別,除非要在別的cpp檔案中呼叫它
static在類和結構內代表什麼
表示類內所有同名變數都代表乙個實體,如果這個屍體的值發生了改變,那麼類中所有的這個實體都同樣會改變。
#includestructentity
};int
main()
; e.print();
e1.print();
std::cin.
get();
}
列印結果是2,3 5,8
#includestructentity
};int
entity::x;
intentity::y;
intmain()
此時的列印結果是兩個5,8,需要注意的是靜態變數無法訪問非靜態變數,如果**做如下修改,那麼靜態函式print將無法訪問非靜態的變數x和y
#includestructentity
};int
main()
使用訪問命名空間的方法來訪問類/結構體中的靜態成員是因為靜態型別是唯一的,無需通過新建類/結構體來實現訪問。如果做以下修改,可以正常執行
#includestructentity
};static
void
print(entity e)
intmain()
本地作用域中(local scope)的靜態變數
需要掌握的變數的生命週期(變數在被刪除之前在記憶體中儲存多久)和作用域(在**可以訪問到這個變數)
區域性靜態變數允許我們定義乙個生命週期是整個程式的變數,但是他的作用域被限制在當前函式中,其實也不一定是函式,可以在任何作用域中宣告靜態變數,函式中的靜態變數和類中的靜態變數其實沒有很大的區別,他們的生命週期是一樣的,唯一區別是類中的靜態變數可以被類內的任何變數訪問,在函式作用域中宣告的靜態變數,對於函式來說是區域性的,就像類的靜態變數對於類來說也是區域性的。如果在函式中宣告乙個靜態變數,那麼在第一次呼叫函式時,這個靜態變數被建立,後續再次呼叫此函式時將不會在建立這個變數。
#includevoidfunc()
intmain()
此函式的輸出結果是三個1,如果將int i=0改為靜態變數,那麼結果將輸出1,2,3
#includevoidfunc()
intmain()
將i設在函式外面作為全域性變數也是一樣的結果,但是當i作為全域性變數時,就意味著我在任何地方都可以呼叫它,所以會有一些意外的發生。
#includestaticint i=0
;void
func()
intmain()
此時輸出結果是1,11,12,如果不想讓程式出現這種效果,此時可以將i變成區域性靜態變數
同樣,區域性靜態變數可以簡化**
#includeclasssingleton
void
hello() {}
};singleton *singleton::s_instance=null;
intmain()
簡化如下
#includeclasssingleton
void
hello() {}
};int
main()
如果singleton instance前面沒有static,因為singleton是在堆疊上建立的,在執行到結束花括號時被銷毀,函式結束,在返回引用時這將會是個嚴重的錯誤,如果將表示引用的「&」去掉將不會有錯,加上了static將會大大延長了instance的生命週期,每次呼叫get()的時候後面的呼叫都會返回到第一次構造的singleton例項。
Java中的static靜態
static關鍵字修飾的方法或者變數不需要依賴於物件來進行訪問,只要類被載入了,就可以通過類名去進行訪問。1 static方法 在非靜態成員方法中是可以訪問靜態成員方法 變數的。但在靜態方法中不能訪問類的非靜態成員變數和非靜態成員方法,因為非靜態成員方法 變數都是必須依賴具體的物件才能夠被呼叫。即使...
C 靜態static的用法
一 靜態類 靜態類與非靜態類的重要區別在於靜態類不能例項化,也就是說,不能使用 new 關鍵字建立靜態類型別的變數。在宣告乙個類時使用static關鍵字,具有兩個方面的意義 首先,它防止程式設計師寫 來例項化該靜態類 其次,它防止在類的內部宣告任何例項欄位或方法。靜態類的主要特性 1 僅包含靜態成員...
C 類中的靜態成員函式 static
為了能方便訪問靜態資料成員,c 定義了一種特殊的成員函式來專門負責對靜態資料成員的訪問,這種函式叫做靜態成員函式。靜態成員函式的定義是在非靜態成員函式的定義前加上static關鍵字。它的訪問方式和靜態資料成員相似,也是通過作用域限定符來訪問,語法如下 類名 靜態成員函式名 引數 作為類的成員,靜態成...