C++非類中和類中的static的作用
一、非類中的static
1、隱藏
static修飾全域性變數的時候,這個全域性變數只能在本檔案中訪問,不能在其它檔案中訪問,即便是extern外部宣告也不可以。static修飾一個函式,則這個函式的只能在本檔案中呼叫,不能被其他檔案呼叫。
2、保持區域性變數永續性
在修飾變數的時候,static修飾的靜態區域性變數只執行一次,而且延長了區域性變數的生命週期,直到程式執行結束以後才釋放。
3、static變數預設初始化為0
二、類中的static
1、靜態資料成員
(1)靜態資料成員不屬於物件,屬於類,所有例項物件共用一份。因此,初始化時使用作用域運算子來標明它所屬類。可以實現多個物件之間的資料共享,又因為它在記憶體中只佔一份空間,如果改變它的值,則各物件中這個資料成員的值都被改變。
類的靜態資料成員既可以通過物件名引用,也可以通過類名引用:
<類物件名>.<靜態資料成員名>
或
如果靜態資料成員的訪問許可權允許的話(即public的成員),可在程式中,按上述格式來引用靜態資料成員。
應用:
需要一個數據物件為整個類而非某個物件服務,同時又力求不破壞類的封裝性,即要求此成員隱藏在類的內部,對外不可見。
靜態資料成員主要用在各個物件都有相同的某項屬性的時候。比如對於一個存款類,每個例項的利息都是相同的。所以,應該把利息設為存款類的靜態資料成員。這有兩個好處,第一,不管定義多少個存款類物件,利息資料成員都共享分配在全域性資料區的記憶體,所以節省儲存空間。第二,一旦利息需要改變時,只要改變一次,則所有存款類物件的利息全改變過來了。
(2)靜態資料成員必須在類外初始化。當然,如果在加上關鍵const, 則是可以在類中進行初始化的。
- a、初始化在類體外進行,而前面不加static,以免與一般靜態變數或物件相混淆;
- b、初始化時不加該成員的訪問許可權控制符private,public等;
- c、初始化時使用作用域運算子來標明它所屬類;
- d、由於靜態成員聲明於類中,操作於其外,所以對其取地址操作,就多少有些特殊 ,變數地址是指向其資料型別的指標 ,函式地址型別是一個“nonmember函式指標”。
靜態資料成員初始化的格式:<資料型別><類名>::<靜態資料成員名>=<值>
(3)靜態資料成員是在程式開始執行時被分配空間,到程式結束之後才釋放,只要類中指定了靜態資料成員,即使不定義物件,也會為靜態資料成員分配空間。
(4)為了防止父類的影響,可以在子類定義一個與父類相同的靜態變數,以遮蔽父類的影響。這裡有一點需要注意:我們說靜態成員為父類和子類共享,但我們有重複定義了靜態成員,這會不會引起錯誤呢?不會,我們的編譯器採用了一種絕妙的手法:name-mangling 用以生成唯一的標誌。
2、靜態成員函式
(1)類的靜態成員函式是屬於整個類而非類的物件,所以它沒有this指標,這就導致了它僅能訪問類的靜態資料成員和靜態成員函式。
靜態方法屬於類,而不是類例項,訪問靜態方法不需要一個例項,而非靜態方法的訪問,必須要先例項化一個物件,所以避免非靜態方法的訪問錯誤,不在靜態方法呼叫非靜態的東西。
- a、非靜態的成員函式可以任意的訪問靜態資料成員和靜態成員函式。
- b、由於沒有this指標的額外開銷,靜態成員函式與類的非靜態成員函式相比速度上會有少許的增長。
(2)不能將靜態成員函式定義為虛擬函式。
因為靜態成員函式屬於類,在記憶體中只有一份。而虛擬函式必須根據物件型別才能知道呼叫哪一個虛擬函式,故虛擬函式是一定要在物件的基礎上才可以的,兩者一個終歸屬於類,一個必依賴於物件,那麼終歸是不能合二為一的 。
(3)靜態成員函式不能宣告為const。
const 修飾成員函式表示 該成員函式不會修改某個該函式所屬的物件(const修飾的成員方法必須有this指標),static不屬於任何物件,沒有this指標。
(4)由於靜態成員函式沒有this指標,所以就差不多等同於nonmember函式,結果就 產生了一個意想不到的好處:成為一個callback函式,使得我們得以將C++和C-based X W indow系統結合,同時也成功的應用於執行緒函式身上。