掌握C++中static關鍵字的多種使用場景

static是什么
在最開始C
中引入了static
關鍵字可以用于修飾變量和函數(shù),后來由于C++
引入了class
的概念,現(xiàn)在static
可以修飾的對象分為以下5種:
成員變量,成員函數(shù),普通函數(shù),局部變量, 全局變量
static的作用
修飾成員變量
static
修飾成員變量之后,該變量會屬于該類,而不是某一個該類的對象。舉個例子,Student
類種有一個count
的變量,在使用static
關鍵字修飾之后,所有Student
的對象共用這1個count
。
調用方式會發(fā)生改變,無法通過 對象名 + . 變量名來調用,而是需要通過類名 + 作用域(::) + 變量名來調用,舉個例子
Studnet s1;
// 會編譯警告 Clang-Tidy: Static member accessed through instance 通過實例調用靜態(tài)成員變量
cout << s1.count << '\n';
// ok
cout << Studnet::count << '\n';
修飾成員函數(shù)
和成員變量一樣,使用static
修飾的成員函數(shù)的生命周期和使用方式都發(fā)生了變化
通過static
修飾的函數(shù),如果訪問非static
成員變量,編譯器會直接報錯
修飾普通函數(shù)
函數(shù)的作用域會發(fā)聲變化,被static修飾的普通函數(shù)只能在本文件內可以見,同一個程序的其他文件將無法調用該函數(shù)。可以在一定程度上解決命名沖突的問題,不過C++提供了namespace
,所以一般不用于修飾普通函數(shù)。
修飾全局變量
和修飾普通函數(shù)一樣,被static
修飾的全局變量的可見性會發(fā)生變化,其他文件將無法調用該全局變量,其余和普通全局變量沒有區(qū)別
修飾局部變量
static
修飾的局部變量被初始化一次之后,每次函數(shù)調用都繼續(xù)使用之前的值,而不是重新進行初始化操作
如何使用static
成員變量
通過在成員變量前面加上關鍵字static
即可
class Studnet {
private:
? static int count;
};
// static修飾的成員變量只能在類外初始化
int Student::count = 0;
// C++17之后可以通過inline的方式在類內初始化,例如
class Studnet2 {
private:
? static inline int count = 0;
};
成員函數(shù)
class Studnet {
public:
? static int init(int number1, int number2) {
? ? ? age = number1; // 編譯報錯 Invalid use of member 'age' in static member function
? ? ? ? count = number2; // ok
? }
private:
? static inline int count = 0;
? int age = 18;
};
普通函數(shù)
static int add(int a, int b) {
? return a + b;
}
全局變量
static int count = 2;
局部變量
void print() {
? static int a = 0;
? ++a;
? cout << a << endl;
}
底層原理
之所以被static
修飾的變量或者函數(shù)的生命周期會超越支配其所在的作用域的本質是因為它在內存中的存儲位置發(fā)生了變化
操作系統(tǒng)為每一個程序創(chuàng)建一個進程用于分配程序運行時需要的資源,其中就包括虛擬內存空間。其中用戶區(qū)的空間分為4個區(qū)域,從低位到高位分別為,全局區(qū),堆區(qū),共享區(qū)和棧區(qū)
而局部變量存放在棧區(qū),隨著函數(shù)的調用和返回被構造和析構,在底層操作系統(tǒng)的角度來看,就是將該變量占用的內存空間給回收了
而成員變量根據(jù)實例被聲明的方式,如果是new關鍵字定義的就存放在堆區(qū),否則就在棧區(qū)。如果是堆區(qū)的對象,不會隨著作用域的離開被析構,只能通過delete關鍵字手動釋放或者程序結束后被操作系統(tǒng)自動回收
而static
修飾之后,操作系統(tǒng)會將該變量存放在全局區(qū),全局區(qū)的變量只會初始化一次,并且在程序結束后被操作系統(tǒng)回收。這也就是為什么static
修飾的變量的生命周期會和程序一樣長的底層原理
而全局區(qū)通常存放的是全局變量,靜態(tài)成員變量和靜態(tài)局部變量。因為全局變量本來就存放在全局區(qū),所以給全局變量加static和不加,除了可見性之外,沒有什么區(qū)別