C++小結--static關鍵字的使用
1 static是什麼
static是c/c++的一個關鍵字,主要有兩個作用:
1 限定作用域,
2 保持變數的持久化。
2 在C語言中static的用法
2.1 全域性靜態變數
用法:在全域性變數前加上關鍵字static,全域性變數就定義成一個全域性靜態變數。 static int temp;
記憶體中的位置:靜態儲存區,在整個程式執行期間一直存在。
初始化:未經初始化的全域性靜態變數會被自動初始化為0(自動物件的值是任意的,除非他被顯式初始化);
作用域:全域性靜態變數在宣告他的檔案之外是不可見的,準確地說是從定義之處開始,到檔案結尾,這樣就可以防止在多個檔案中變數重名的問題。
2.2 區域性靜態變數
在區域性變數之前加上關鍵字static,區域性變數就成為一個區域性靜態變數。
記憶體中的位置:靜態儲存區
初始化:未經初始化的全域性靜態變數會被自動初始化為0(自動物件的值是任意的,除非他被顯式初始化);
作用域:作用域仍為區域性作用域,當定義它的函式或者語句塊結束的時候,作用域結束。但是當局部靜態變數離開作用域後,並沒有銷燬,而是仍然駐留在記憶體當中,只不過我們不能再對它進行訪問(不是完全不能訪問,我們可以通過指標來訪問,不過不建議那樣做),直到該函式再次被呼叫,並且值不變。
2.3 靜態函式
在函式返回型別前加關鍵字static,函式就定義成靜態函式。函式的定義和生命在預設情況下都是extern的,但靜態函式只是在宣告他的檔案當中可見,不能被其他檔案所用;
3 在C++中static的用法
我們知道,C++是繼承並發展C語言的,所以static關鍵字在C++中也保留了C語言中的三個基本用法,不過還對它進行了擴充,主要是用在類中。
3.1 類的靜態成員
class A{
private:
static int val;
};
在C++中必須對他進行初始化,初始化時使用作用域運算子來標明他所屬類,其屬於該類的所有成員共有,只有一個拷貝;也就是說,我們在使用該類申明多個物件時,各個物件都共享此一個變數。我們可以利用這個特性實現單例模式,後續會介紹。
3.2 類的靜態成員函式
class A{
private :
static int func(int x);
};
實現的時候也不需要static的修飾,因為static是宣告性關鍵字;類的靜態函式是該類的範疇內的全域性函式,不能訪問類的私有成員,只能訪問類的靜態成員,不需要類的例項即可呼叫;實際上,他就是增加了類的訪問許可權的全域性函式;
void A::func(int);
靜態成員函式可以繼承和覆蓋,但無法是虛擬函式;
3.3 實踐演示
#include <iostream>
using namespace std;
class c_stu
{
public:
int a;
//1、靜態成員屬於類的一個屬性,不屬於一個物件的屬性。
//2、在編譯器編譯的時候,他就已經存在。
//3、靜態成員可以作為類建立物件的一個溝通的橋樑。
static int b;
//靜態成員函式必須使用靜態成員變數,不能訪問非靜態成員變數
static void func();
};
//類外初始化
int c_stu::b = 10;
//類外實現,不需要加關鍵字static
void c_stu::func()
{
int x = 100;
int y = 200;
int z = x + y;
b = 13;
cout << "&z = " << &z << endl;
cout << "&b = " << &b << endl;
}
int main()
{
//類名作用域可以直接訪問靜態成員變數和靜態成員函式
cout << c_stu::b << endl;
c_stu::func();
//物件也可以訪問
c_stu stu;
cout << stu.b << endl;
stu.func();
system("pause");
return 0;
}
執行結果:
10
&z = 0113F8C8
&b = 00BEC000
13
&z = 0113F8C8
&b = 00BEC000
請按任意鍵繼續. . .
結果分析:我們看到直接通過類呼叫和通過物件呼叫,z和b的地址是一樣的,所以證明了z和b只有一份,也就是說static修飾的函式和變數是類共有的,所有的物件都訪問同一個函式和變數。這也就可以解釋為什麼static成員函式不能訪問非靜態成員變數。
4 總結
static關鍵字在C++中擴充了其內容,主要是在類中進行了擴充。需要好好體會並理解這樣設計的目的,很多類中很巧妙的利用static的特性來實現一些有用的功能,比如類的例項化物件個數計數,單例模式實現等等。