1. 程式人生 > >【轉】C++中static用法總結

【轉】C++中static用法總結

地址:https://www.cnblogs.com/qiaoconglovelife/p/5323086.html

1.用於區域性變數

C++中區域性變數有三種:
(1)auto:此關鍵詞常常省略。auto type a 常常簡寫為type a。
如:int a=auto int a
儲存在記憶體的棧中,只在此區域性區域有定義,程式執行過此區域性區域自動釋放。

(2)static:有以下特點:

  • 宣告在區域性區域,第一次執行時定義,以後就不再定義;
  • 同auto和register,只在其定義的區域性區域有定義;
  • 區別與auto和register,static區域性變數儲存在記憶體的靜態變數區。所以下次執行到此區域性區域時,上次的結果值得以保留。
int get()
{
      static int a=0;
      return a++;    
}    
int main()
{
      cout<<get()<<get();
      return 0;    
}
//程式輸出:01。第二次不再執行static變數a的定義。

(3)register:基本同auto,只是直接儲存在CPU的暫存器組。

2.用於全域性變數和全域性函式

你可能會問?用在區域性就儲存在記憶體的靜態變數區了,那麼定義到全域性又有什麼作用呢?
  這種定義常用於有多個文件的工程的變數/函式保護。舉個栗子:

static int a,
static void fun();

上面定義了一個全域性static變數a,一個static函式fun。
  加上static可以保證其它文件不可以訪問到他們。回想一下,怎樣讓一個變數在多個文件中都可以使用?extern!對的。
  Talk is cheap, I will show you the code:

/*FileName: File1.cpp */
int a;

/*FileName: File2.cpp*/
extern int a;

在File1.cpp中定義了int a,只需在File2.cpp中extern一下,便可以把File1.cpp中的變數a直接拿來用,他們是同一個變數。
  那麼,如果File1.cpp中,我們把a的定義換為static int a,那麼在File2.cpp中extern int a會發生什麼呢?肯定報錯啦,我剛剛都說過了,static定義在全域性,可以起到保護作用,保證此定義只能被本文件使用。
  函式的情況也是一樣的。

3.用於成員變數

class A
{
public:      
    static int a; 
};

a便成為了A的靜態成員變數。
(1)它只屬於A,不屬於A的任何一個物件。
(2)它不能被A的建構函式初始化,需要單獨定義、初始化,其方法和類成員函式的定義相同。
(3)兩種訪問方法:
  1)通過類A::a; 2)通過類物件/指標:obj_A.a,ptr_A->a。
  例子:

class A
{
public:
    static int a;
};
int A::a = 100 ;

int _tmain(int argc, _TCHAR* argv[])
{
    A obj_A;
    A *ptr_A=&obj_A;
    cout << A::a << " " << obj_A.a << " " << ptr_A->a << endl;    
    
    while (1);
    return 0;
}

4.用於成員函式

  成員函式有了static的修飾便成了靜態成員函式,它的基本屬性與靜態成員變數一致。另外,由於虛擬函式要在物件中建立虛表,所以虛擬函式無法為static函式

小總結:不能為虛的幾種函式:普通函式、友元函式、建構函式、靜態成員函式、行內函數。

靜態成員函式最大的特點是它沒有this指標,它的其它特性都因此而來。如果對一個靜態成員函式求指標,得到的將不是一個指向member function函式的指標,而是指向普通function的指標。例如:

有classA一個函式static void fun();&classA::fun()會得到void()(),而不是void(classA::)()。也就是說,static最大程式上近似於非成員函式。這種特性提供了一個意想不到的好處:static成員函式可以作為callback函式!

C++把靜態成員函式稱作類方法,把其他成員函式稱作例項方法。不同之處:

(1)類方法只有一份例項,不屬於任何一個物件。

(2)類方法只能呼叫類方法,不能呼叫例項方法。而例項方法可以呼叫類方法。

(3)類方法不能呼叫非靜態成員變數

最後一個栗子:

class cA
{
public:
    int objVar1;
    static int classVar1;
    static void classFun1()
    {
        classVar1 = 0;
        objVar1 = 0;//錯誤!!!類方法無法訪問非靜態成員函式
        classFun2();
        objFun1();//錯誤!!!類方法無法呼叫例項方法
    };
    static void classFun2(){};
    void objFun1()
    {
        classVar1 = 0;
        objVar1 = 0;
        classFun1();
                objFun2();     
    };
    void objFun2(){};
};