歡迎您光臨本站 註冊首頁

一文讀懂c++之static關鍵字

←手機掃碼閱讀     zmcjlove @ 2020-06-26 , reply:0

一、靜態變量

與C語言一樣,可以使用static說明自動變量。根據定義的位置不同,分為靜態全局變量和靜態局部變量。

  • 全局變量是指在所有花括號之外聲明的變量,其作用域範圍是全局可見的,即在整個項目文件內都有效。使用static修飾的全局變量是靜態全局變量,其作用域有所限制,僅在定義該變量的源文件內有效,項目中的其他源文件中不能使用它。

  • 塊內定義的變量是局部變量,從定義之處開始到本塊結束處為止是局部變量的作用域。使用static修飾的局部變量是靜態局部變量,即定義在塊中的靜態變量。靜態局部變量具有局部作用域,但卻具有全局生存期。

  • 靜態局部變量具有局部作用域,但卻具有全局生存期。也就是說,靜態局部變量在程序的整個運行期間都存在,它佔據的空間一直到程序結束時才釋放,但僅在定義它的塊中有效,在塊外並不能訪問它。

  • 靜態變量均存儲在全局數據區,靜態局部變量只執行一次初始化。如果程序未顯式給出初始值,則相當於初始化為0;如果顯式給出初始值,則在該靜態變量所在塊第一次執行時完成初始化。

  #includeusing namespace std;    //全局靜態變量  static int glos_s=10;  //全局變量  int glos_a=10;    void f(){    int a=1; //局部變量a    static int fs=1; //靜態局部變量fs,完成初始化。    a+=2;    fs+=2;    glos_s+=10;    glos_a+=10;    cout<<"在f中:局部變量a="<<a<<" 靜態局部變量fs="<<fs<<" 全局變量glos_a="<<glos_a<< " 全局靜態變量glos_s=" << glos_s <<endl;  }  int main(){     f(); //在f中:局部變量a=3 靜態局部變量fs=3 全局變量glos_a=20 全局靜態變量glos_s=20     f(); //在f中:局部變量a=3 靜態局部變量fs=5 全局變量glos_a=30 全局靜態變量glos_s=30    return 0;   }

 

二、類中的static

1、定義類的靜態成員

類的靜態成員有兩種:靜態成員變量和靜態成員函數。在類體內定義類的成員時,
 在前面添加static關鍵字後,該成員即成為靜態成員。

  • 類的靜態成員被類的所有對象共享,不論有多少對象存在,靜態成員都只有一份保存在公用內存中。對於靜態成員變量,各對象看到的值是一樣的。

  • 定義類靜態成員變量時,在類定義中聲明靜態成員變量,然後必須在類體外定義靜態成員變量的初值。這個初值不能在類體內賦值。

  • 給靜態成員變量賦初值的格式如下:類型 類名::靜態成員變量=初值;

  • 注意,在類體外為靜態成員變量賦初值時,前面不能加static關鍵字,以免和一般的靜態變量相混淆。在類體外定義成員函數時,前面也不能加static關鍵字。

2、類靜態成員的使用

訪問靜態成員時,成員前面既可以用類名作前綴,也可以使用對象名或對象指針作前綴。這與訪問類成員時僅能使用對象名或對象指針作前綴是不同的。訪問類靜態成員的一般格式如下:

  • 類名::靜態成員名

  • 對象名.靜態成員名

  • 對象指針->靜態成員名

類的靜態成員函數沒有this指針,不能在靜態成員函數內訪問非靜態的成員,即通常情況下,類的靜態成員函數只能處理類的靜態成員變量。靜態成員函數內也不能調用非靜態成員函數。

  #includeusing namespace std;    class Student{    public:      int id;      string name;      static int money;      static void printlnMoney(Student &stu);    };  //靜態成員必須在類體外初始化,並且不能在類體內賦值  int Student::money=10000;  //靜態成員函數的實現  void Student::printlnMoney(Student &stu){    cout << "name:" << stu.name <<" money:" << stu.money << endl;  }    int main(){    Student stu;    stu.id=1;    stu.name="小米";    //使用對象調用靜態成員    stu.printlnMoney(stu);//name:小米 money:10000    Student *stu2=new Student();    stu2->id=1;    stu2->name="美團";    //使用指針調用靜態成員    stu2->printlnMoney(*stu2);//name:美團 money:10000    //使用類名調用靜態成員    Student::money=50000;    Student::printlnMoney(*stu2);//name:美團 money:50000    Student::printlnMoney(stu);//name:小米 money:50000    return 0;   }

 

3、普通成員與靜態成員

對於普通成員變量,每個對象有各自的一份,而靜態成員變量只有一份,被同類所有對象共享。普通成員函數一定是作用在某個對象上的,而靜態成員函數並不具體作用在某個對象上。

訪問普通成員時,要通過“對象名.成員名”等方式,指明要訪問的成員變量是屬於哪個對象的,或要調用的成員函數作用於哪個對象;

訪問靜態成員時,則可以通過“類名::成員名”的方式訪問,不需要指明被訪問的成員屬於哪個對象或作用於哪個對象。
 因此,甚至可以在還沒有任何對象生成時就訪問一個類的靜態成員。非靜態成員的訪問方式其實也適用於靜態成員,也就是可以通過“對象名.成員名”的方式訪問,效果和“類名::成員名”這種訪問方式沒有區別

在通常情況下,除一種情況外,類的成員函數之間是允許互相調用的。具體來說,靜態函數與靜態函數之間、非靜態函數與非靜態函數之間是可以相互調用的,非靜態成員函數內可以調用靜態成員函數,但靜態成員函數內不能調用非靜態成員函數



[zmcjlove ] 一文讀懂c++之static關鍵字已經有250次圍觀

http://coctec.com/docs/c/language/show-post-239737.html