天天看點

C/C++ ---static函數,static成員函數,static變量,static成員變量static成員變量:

首先說一下記憶體的五個區:

  • 棧(stack):由編譯器自動配置設定釋放,存放函數的參數值,局部變量的值(除static),其操作方式類似于資料結構中的棧。
  • 堆(heap):一般由程式員配置設定釋放,若程式員不釋放,程式結束時可能由OS回收。注意它與資料結構中的堆(優先隊列)是兩回事,配置設定方式是類似于連結清單。
  • 全局區(靜态區):全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域,未初始化的全局變量和靜态變量在相鄰的另一區域,程式結束後由系統釋放。
  • 文字常量區:常量字元串放在這裡,如char str[]="hello",程式結束後由系統釋放,差別const修飾的變量。
  • 程式代碼區:存放函數體的二進制代碼。

static變量:

     靜态局部變量儲存在全局資料區(靜态區),而不是儲存在棧中,每次的值保持到下一次調用,知道下次賦新值。

static成員變量:

     定義必須在類定義體的外部,在類的内部隻是聲明,聲明必須加static,定義不需要。

class A
{
   public:
      //聲明static變量,任何聲明都不可初始化,如extern外部變量
      static int a;
   private:
      static int b;
};

//定義static成員變量,可初始化
int A::a = 5;

//私有靜态成員變量,不能直接用類名調用或者對象調用,隻能在類内調用
int A::b = 1;  //error!

           

    static變量跟類相關,跟具體的對象無關,static變量為類的所有執行個體對象所共享,某個執行個體對象修改了該靜态成員變量,其修改值為該類所有其他執行個體對象可見。

#include<iostream>

using namespace std;

class A
{
   public:
       //聲明為static變量,任何聲明都不可初始化,如extern外部變量
       static int a;
   private:
       static int b;
   public:
       static int getValue(){
              return a;
           }
 };

//定義static成員變量,可初始化
int A::a = 5;

int main(int argc,char** argv)
{
    A* instanceA=new(A);
    A* instanceB=new(A);
    
    instanceA->a = 1;
    cout<<A::a<<endl;
    cout<<instanceA->getValue()<<endl;   //輸出1
    cout<<instanceB->getValue()<<endl;   //輸出1

    return 0;
}
           

staic 函數:

      a.cpp  

#include<cstdio>

int a = 5;
void printHello()
{
     printf("Hello world!\n");
}
           

      b.cpp

#include<cstdio>

//聲明
void printHello();

int main(int argc,char** argv)
{
    //聲明
    extern int a;
    printf("a=%d\n",a);
    printHello();
    
    return 0;
}
           

g++ a.cpp b.cpp -o ab.out  輸出

a=5
Hello,world!
           

分析:如果在a.cpp中的int a=5; 定義前面加上static修飾,再次去編譯,在b.cpp中會報未定義錯誤。類似的,在a.cpp中的void printHello()函數前面加上static修飾,再次去編譯,一樣也會報未定義錯誤。很明顯,所有未加static修飾的函數和全局變量具有全局可見性,其他的源檔案也能夠通路,如果加上static修飾,則隻能在目前源檔案中可見,對其他源檔案是不可見的。static的這一特性可以在不同的檔案中定義同名函數和同名變量,而不必擔心命名沖突。

static成員函數:

      與成員變量一樣,靜态成員函數隻和類相關,跟具體的對象無關,可以通過類名來調用,當然也可以通過執行個體對象來調用。

static成員函數裡面不能通路非靜态成員變量,也不能調用非靜态成員函數。

     靜态成員函數沒有this隐含指針修飾,也不能為virtual修飾。

c++

繼續閱讀