C與C++中的static的關鍵詞的作用
這裡分成兩個方面來講:
1.對於C語言
原則一:只用進行一次初始化
但是有一個原則必須講,static所儲存的位置:
還是把一個程序進行的位置放出:
.text:指的是程式碼段
.data和.bss是我們要重點討論的段:
這兩個段儲存著我們全域性變數(包括全域性靜態變數和全域性變數)
.data:儲存著我們已經初始化的全域性變數和全域性靜態變數
.bss(block of start symbol)(雖然我更喜歡叫它best save space):儲存著我們未初始化的全域性變數和全域性靜態變數。
從這點可以明白我們的靜態變數不在堆中,所以只用進行一次初始化就可以存在空間中,類似於全域性變數。
其他段簡單說明一下:
.symtab:符號段。
.debug .line這兩個段在我們除錯的過程中才會出現,或許我們在加入-g的時候才會出現這兩個段。
原則二:對於多檔案引用的過程中,只能本檔案使用該變數或者函式
這也是static關鍵詞區別於全域性變數的地方,我們利用static來保護所在檔案的static 變數以及static 函式不被檔案訪問。
具體的程式碼暫時不寫啦,這個好寫。
2.對於C++而言:
對於C++而言,我們無非要考慮的都是static放在物件裡面的情況。
也就是static成員變數和static成員函式的區別:
(1). static 成員變數
根據我們的原則一,static存在於.data段中,被這個類的所有物件使用,所有物件共用同一個類的static成員變數,並在類外進行初始化。(常見的例子就是:銀行的總收益情況,所有物件加的收益都得加在一起),這裡有個例子可以說明:
#include<iostream>
using namespace std;
class Point2d{
public:
virtual void Foo(){}
virtual void Boo(){}
virtual void non_overwrite(){}
protected:
float _x, _y;
};
class Vertex: public Point2d{
public:
virtual void Foo(){}
virtual void BooVer(){}
protected:
Vertex *next;
};
class Point3d: public Point2d{
public:
virtual void Boo3d(){}
protected:
float _z;
};
class Vertex3d: public Vertex, public Point3d{
public:
void test(){}
static void test3(){}
static int a;
protected:
float mumble;
};
int Vertex3d::a=1;
int main()
{
Vertex3d vertex;
vertex.test();
cout<<"the size of Vertex3d: "<<sizeof(Vertex3d)<<endl;
return 0;
}
不過值得注意的是,加了staitc變數對這個sizeof(Vertex3d)不會造成大小的變數:
但是,把this指標打印出來,還是會特定看到static變數,如下圖所示:
大小不會發生改變。
(2) 靜態成員函式
靜態成員函式可就厲害了,這裡要說明幾個特性:
1.我們在呼叫物件的成員函式的時候,編譯器會傳入一個this指標,通過這個this指標我們可以訪問物件的靜態和非靜態變數。
2。但是我們我們的靜態成員函式不會傳入this指標,這就導致了我們不能訪問物件的非靜態變數以及其他物件的變數,只用訪問自己的非靜態變數。
Reference:
1.分析類的成員變數的各種測試
https://www.cnblogs.com/codingmengmeng/p/5906282.html
2.分析static在C/C++的用法:
https://www.cnblogs.com/songdanzju/p/7422380.html