天天看點

C/C++ static 用法總結



                             static用法

  a.靜态局部變量,成為靜态局部變量(擁有記憶功能和全局存儲權限)

  b.靜态全局變量(限制對應全局變量被被其他檔案調用)

  c.靜态函數

  d.靜态類成員(辨別此成員屬于類而非屬于某個特定對象)

 1.靜态局部變量

   1.1靜态局部變量在函數内定義,擁有靜态存儲期限而不再是自動存儲期限,因為靜态存儲期限的變量擁有永久的

      存儲單元,是以在整個程式存儲期間都會保留變量的值,盡管退出函數後變量依然存在,但不能使用。

   1.2靜态局部變量始終擁有塊作用域。(與自動變量作用域相同)

   1.3對基本類型的靜态局部變量在定義時若為賦初值,則系統自動指派為0.

   1.4舉例如下:

     void static_local_variable()

     {

     static int count = 0;

     count++;

     }

     第一次進入此函數,靜态變量count被初始化為0(若不初始化,系統會自動初始化為0),接下來執行count++。

  而之後調用此函數則隻執行count++.

     此函數與以下代碼實作同樣的功能:

     int count = 0;

     void fuc()

     {

       count++;

     }

  2.靜态全局變量

    2.1靜态存儲期限。如同聲明為static的局部變量一樣,外部變量擁有靜态存儲期限,存儲在外部變量中的值獎

       被永久的保留下來。

    2.2檔案作用域。外部變量擁有檔案作用域;從變量被聲明的位置開始,一直到所在檔案的末尾。是以,跟随在

       外部變量之後聲明的所有函數都可以通路。

    2.3舉例如下:

      //xxxx.cpp

      void fucOne()

      {

       sCount++;

       count++;

      }

      static int sCount = 0;

      int count = 0;

      void fucTwo()

      {

       sCount++;

       count++;

      }

      a.fucOne()定義在sCount和count變量之前,編譯時會提示未聲明标示符。而fucTwo()定義在兩變量之後,在

        fucTwo()中則可正常使用。且在其他.cpp檔案中不可通路。

      b.若兩個.cpp檔案聲明了同名的全局變量,其本質為生命了兩個獨立的靜态全局變量。

      c.count變量則可共享,在xxx.h檔案中對其聲明 extern int count;在任何一個包含此頭檔案的.cpp檔案中初始化一次即可共享此全局變量。而同樣的方法卻不适用于靜态變量。

      (強烈建議:不要将靜态/靜态變量定義在.h檔案中)

  3.static函數

    3.1内部函數(static函數,不可再其他檔案中調用)

      如果在一個原檔案中定義的函數隻能被此源檔案使用,則在函數類型前加 static 關鍵字即可。(利用了

    static的檔案作用域)

      舉例如下:

      static void fuc()

      {

      }

    3.2外部函數(可在其他檔案中調用)

      舉例如下:

      //file.cpp

      [extern] void fuc()

      {

      }

      //main.cpp

      int main()

      {

       extern void fuc();

      }

    4.靜态類成員

      4.1 類的靜态成員可以是private的或public的。靜态資料成員可以是常量、指針、引用、類類型等。

      4.2 其靜态成員屬于類而非某個特定對象。其靜态成員函數中也不能使用this指針。

      4.2 類靜态成員的使用

        a.定義并初始化

          一般來說,不能在類的内部初始化靜态資料成員,相反的,必須在類的外部定義和初始化每個靜态資料成

        員。

          舉例如下:

        //xxxx.h

        class A

        {

          private:

            static int count;//聲明

          public:

            static  void fuc();

        }

        int A::count = 0;//定義、初始化

        (注意:最好将靜态資料成員的定義初始化放在對應的.cpp檔案中,若像如上定義,在此頭檔案被多次包含時,靜态成員會被重複定義)

        b.類内初始化

          如果某個資料成員的應用場景僅限于編譯器可以替換它的情況,則一個初始化的const或constexpr static不需要分别定義.

          舉例如下:

          class Account

          {

            public: 

              static doule fuc(){};

            private:

              static constexpr int NUM = 30;

              int array[NUM];

          }

          相反若它将用于值不能替換的場景中,則該成員必須有一條定義語句:

          舉例如下:

          constexpr int Account::NUM;//隻定義,不初始化,初始化已在類内提供

          (建議:即使一個常量靜态資料成員在類内被初始化了,通常情況下也應該在類外定義一下該成員)

        c.靜态成員的兩個應用

          (1)靜态成員可以是不完全類型(不完全類型:隻聲明,未定義)

          (2)可以用靜态成員作為預設實參