c是面向過程語言,在c中,static關鍵字主要作用有以下三個作用:
全域性靜態變數
區域性靜態變數
靜態函式
c++在c的基礎上,拓展了static在物件導向設計中的作用,新增了以下兩種功能:
靜態資料成員
靜態成員函式
下面將一一介紹static的5種作用。
靜態全域性變數和全域性變數都作為資料共享而存在,而且都儲存在全域性資料區,兩者有何區別呢?
靜態全域性變數只能在本檔案中共享,而全域性變數可以在整個專案中共享。很顯然,全域性變數破壞了程式的封裝性,應盡量避免使用。下面是static作為靜態全域性變數的特點:
靜態區域性變數就很好理解了,相對於區域性變數(儲存在棧上),其生命週期會延長到程式結束(儲存在全域性資料區,同全域性變數和靜態全域性變數)。需要記住的是:靜態區域性變數並不屬於某個特定的函式或區域塊,其作用域是全域性的。舉個栗子:
#include int fun(void)
int count = 1;
int main(void)
程式輸出結果為:
靜態區域性變數在程式編譯時就已經在全域性資料區完成初始化操作,因此fun函式中的賦值操作從來就沒執行過。下面是靜態區域性變數的特點:
靜態函式和靜態全域性變數一樣具備「隱藏」功能,只能在本檔案中使用,不能被其他檔案共享。因此其他檔案可以定義 同名函式而不會發生衝突。
在oop中,為了解決同類物件之間的資料共享,在類定義時在該資料成員前加上static,使之成為靜態資料成員就可以減少記憶體分配、實現資料共享的目的,因為此時該資料成員不屬於任何特定物件,只屬於該類。舉個栗子:
#include using namespace std;
class box
;box::box(int w, int len)
int box::volume()
int box::height = 10; //靜態資料成員初始化,必須在類外
int main(void)
輸出為:
10 10
103000
總結一下靜態資料成員的特點:
• 對於非靜態資料成員,每個類物件都有自己的拷貝。而靜態資料成員被當作是類的成員。無論這個類的物件被定義了多少個,靜態資料成員在程式中也只有乙份拷貝,由該型別的所有物件共享訪問。也就是說,靜態資料成員是該類的所有物件所共有的。對該類的多個物件來說,靜態資料成員只分配一次記憶體,供所有物件共用。所以,靜態資料成員的值對每個物件都是一樣的,它的值可以更新;
• 靜態資料成員儲存在全域性資料區。靜態資料成員定義時要分配空間,所以不能在類宣告中定義。
• 靜態資料成員和普通資料成員一樣遵從public,protected,private訪問規則;
• 因為靜態資料成員在全域性資料區分配記憶體,屬於本類的所有物件共享,所以,它不屬於特定的類物件,在沒有產生類物件時其作用域就可見,即在沒有產生類的例項時,我們就可以操作它;
• 靜態資料成員初始化與一般資料成員初始化不同。靜態資料成員初始化的格式為:
<資料型別><類名>::<靜態資料成員名>=<值>
• 類的靜態資料成員有兩種訪問形式:
<類物件名>.<靜態資料成員名> 或 <類型別名>::<靜態資料成員名>
如果靜態資料成員的訪問許可權允許的話(即public的成員),可在程式中,按上述格式來引用靜態資料成員 ;
• 靜態資料成員主要用在各個物件都有相同的某項屬性的時候。比如對於乙個存款類,每個例項的利息都是相同的。所以,應該把利息設為存款類的靜態資料成員。這有兩個好處,第一,不管定義多少個存款類物件,利息資料成員都共享分配在全域性資料區的記憶體,所以節省儲存空間。第二,一旦利息需要改變時,只要改變一次,則所有存款類物件的利息全改變過來了;
• 同全域性變數相比,使用靜態資料成員有兩個優勢:
1. 靜態資料成員沒有進入程式的全域性名字空間,因此不存在與程式中其它全域性名字衝突的可能性;
2. 可以實現資訊隱藏。靜態資料成員可以是private成員,而全域性變數不能。
和靜態資料成員一樣,靜態成員函式不屬於任何類的物件,而是類的一部分,因此類可通過域作用符::直接呼叫該函式。靜態成員函式的根本作用是為了處理靜態資料成員。和非靜態成員函式的根本區別在於:非靜態成員函式有this指標因而可以訪問類的所有資料成員,而靜態成員函式無this指標只能訪問靜態資料成員,而不能訪問非靜態資料成員。舉個栗子:
#include using namespace std;
class myclass
;int myclass::sum = 0;//定義並初始化靜態資料成員
myclass::myclass(int a, int b, int c)
void myclass::getsum() //靜態成員函式的實現
{ // cout<
輸出為:
sum=6
sum=21
sum=21
總結一下靜態成員函式的特點:
• 出現在類體外的函式定義不能指定關鍵字static;
• 靜態成員之間可以相互訪問,包括靜態成員函式訪問靜態資料成員和訪問靜態成員函式;
• 非靜態成員函式可以任意地訪問靜態成員函式和靜態資料成員;
• 靜態成員函式不能訪問非靜態成員函式和非靜態資料成員;
• 由於沒有this指標的額外開銷,因此靜態成員函式與類的全域性函式相比速度上會有少許的增長;
• 呼叫靜態成員函式,可以用成員訪問操作符(.)和(->)為乙個類的物件或指向類物件的指標呼叫靜態成員函式,也可以直接使用如下格式:
<類名>::<靜態成員函式名>(<參數列>)
呼叫類的靜態成員函式。
以上。
ref:
《c++程式設計》
解析關鍵字static
大家都知道static的意思是靜態的,靜止的,同樣的,不管在c語言還是c 中,static作為關鍵字的意思仍為靜止的,靜態的。現在我們就來仔細談下static在c語言和c 中的用法。c語言 static可修飾變數和函式。1.static在修飾變數時,又可分為修飾區域性變數和全域性變數。1 在修飾區域...
C C 中的static關鍵字
關鍵字extern和static用來說明具有靜態儲存期的變數和函式。用static宣告的區域性變數只能被定義該變數的函式所識別,但是不同於自動變數的是,static變數在其函式被呼叫退出後,仍保留其值。下次函式被呼叫時,可以訪問最近一次被修改後的值。static變數的宣告方法如下 static in...
C C 中static關鍵字詳解
靜態變數作用範圍在乙個檔案內,程式開始時分配空間,結束時釋放空間,預設初始化為0,使用時可以改變其值。如果一區域性變數被宣告為static,那麼將只有唯一的乙個靜態分配的物件,它被用於在該函式的所有呼叫中表示這個變數。這個物件將只在執行執行緒第一次到達它的定義使初始化。用法2 區域性靜態物件 對於區...