[C/C++]static關鍵字用法總結

Static關鍵字用法總結

 

static關鍵字是C, C++中都存在的關鍵字。static從字面理解,是靜態的 意思,與此相對應的,應該是動態的

static的作用主要有以下3個:

1、擴展生存期;

2、限制作用域;

3、唯一性;

 

1、擴展生存期

這一點主要是針對普通局部變量和static局部變量來說的。聲明爲static的局部變量的生存期不再是當前作用域,而是整個程序的生存期。

在程序中,常用內存類型主要有堆、棧和靜態存儲區。要理解static局部變量就必須首先理解這三種內存類型。

 

C/C++局部變量按照存儲形式可分爲三種auto, static, register

(譚浩強174-175)

局部變量的默認類型都是auto,從棧中分配內存。

auto的含義是由程序自動控制變量的生存週期,通常指的就是變量在進入其作用域的時候被分配,離開其作用域的時候被釋放。

static變量,不管是局部還是全局,都存放在靜態存儲區。

表面意思就是不auto,變量在程序初始化時被分配,直到程序退出前才被釋放;也就是static是按照程序的生命週期來分配釋放變量的,而不是變量自己的生命週期如果在main前設置斷點,然後查看static變量,已經被初始化,也就是說static在執行main函數前已經被初始化。也就是在程序初始化時被分配。

 

--------------------------------------------------------------------------------------------------------------------------

堆:由程序員自己分配釋放(用malloc和free,或new和delete) ,如果我們不手動釋放,那就要到程序結束才釋放。如果對分配的空間在不用的時候不釋放而一味的分配,那麼可能會引起內存泄漏,其容量取決於虛擬內存,較大。

棧:由編譯器自動分配釋放,其中存放在主調函數中被調函數的下一句代碼、函數參數和局部變量,容量有限,較小。

靜態存儲區:由在編譯時由編譯器分配,由系統釋放,其中存放的是全局變量、static變量和常量.

區別:

1)   堆是由低地址向高地址擴展,棧是由高地址向低地址擴展。

2)   堆是不連續的空間,棧是連續的空間。

3)   在申請空間後,棧的分配要比堆的快。對於堆,先遍歷存放空閒存儲地址的鏈表、修改鏈表、再進行分配;對於棧,只要剩下的可用空間足夠,就可分配到,如果不夠,那麼就會報告棧溢出。

4)   棧的生命期最短,到函數調用結束時;靜態存儲區的生命期最長,到程序結束時;堆中的生命期是到被我們手動釋放時(如果整個過程中都不手動釋放,那就到程序結束時)。

--------------------------------------------------------------------------------------------------------------------------

 

2、限制作用域

這一點相對於普通全局變量和static全局變量來說的。

對於全局變量而言,不論是普通全局 變量還是static全局變量,其存儲區都是靜態存儲區,因此在內存分配上沒有什麼區別。

 別在於:

1)  普通的全局變量和函數,其作用域爲整個程序或項目,外部文件(其它cpp文件)可以通過extern關鍵字訪問該變量和函數。一般不提倡這種用法,如果要在多個cpp文件間共享數據,應該將數據聲明爲extern類型。

     

        在頭文件裏聲明爲extern

extern int g_value;     // 注意,不要初始化值!

然後在其中任何一個包含該頭文件的cpp中初始化(一次)就好:

int g_value = 0;     // 初始化一樣不要extern修飾,因爲extern也是聲明性關鍵字;

然後所有包含該頭文件的cpp文件都可以用g_value這個名字訪問相同的一個變量;

 

2)  static全局變量和函數,其作用域爲當前cpp文件,其它的cpp文件不能訪問該變量和函數。如果有兩個cpp文件聲明瞭同名的全局靜態變量,那麼他們實際上是獨立的兩個變量。

 

static函數的好處是不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名。

 

頭文件中的static變量

如果在一個頭文件中聲明:

       static int g_vaule = 0;

      那麼會爲每個包含該頭文件的cpp都創建一個全局變量,但他們都是獨立的;所以也不建議這樣的寫法,一樣不明確需要怎樣使用這個變量,因爲只是創建了一組同名而不同作用域的變量。

 

3、數據唯一性

這是C++static關鍵字的重用。主要指靜態數據成員/成員函數。

表示屬於一個類而不是屬於此類的任何特定對象的變量和函數這是與普通成員函數的最大區別也是其應用所在比如在對某一個類的對象進行計數時計數生成多少個類的實例就可以用到靜態數據成員在這裏面, static既不是限定作用域的也不是擴展生存期的作用而是指示變量/函數在此類中的唯一性這也是屬於一個類而不是屬於此類的任何特定對象的變量和函數的含義因爲它是對整個類來說是唯一的,因此不可能屬於某一個實例對象的. (針對靜態數據成員而言成員函數不管是否是static, 在內存中只有一個副本普通成員函數調用時需要傳入this指針, static成員函數調用時沒有this指針. )

static數據成員的初始化:

(1) 初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆。

(2) 初始化時不加該成員的訪問權限控制符privatepublic等。

(3) 初始化時使用作用域運算符來標明它所屬類,因此,靜態數據成員是類的成員,而不是對象的成員。

(4) 靜態數據成員是靜態存儲的,它是靜態生存期,必須對它進行初始化。

 

Static成員函數

靜態成員函數和靜態數據成員一樣,它們都屬於類的靜態成員,它們都不是對象成員。因此,對靜態成員的引用不需要用對象名。

靜態成員函數僅能訪問靜態的數據成員,不能訪問非靜態的數據成員,也不能訪問非靜態的成員函數,這是由於靜態的成員函數沒有this指針



reference:http://blog.csdn.net/ljinddlj/article/details/2495209

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章