1. 程式人生 > >C與C++中的static的關鍵詞的作用

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