一.全局靜態變量 no-local static(全局變量前加static關鍵字)
- 全局靜態變量儲存在靜態存儲區,在程序運行期間一直存在。
- 初始化:未經初始化的全局靜態變量自動初始化為0(靜態全局對象值隨機)
- 作用域:在聲明它的文件之外不可見,從定義之處開始,到文件結尾。
二.局部靜態變量 local static(局部變量前加static)
- 同no-local static一樣儲存在靜態存儲區。
- 初始化:等同於no-local static.
- 作用域:為局部作用域, 函數或語句塊結束時結束。但當local static離開作用域后並未被銷毀,仍駐留在內存中,只不過不能再對它訪問,直到該函數再次被調用,並且值不變。
- 區別:靜態局部變量具有局部作用域,它只被初始化一次,自從第一次被初始化直到程序運行結束都一直存在,它和全局變量的區別在於全局變量對所有的函數都是可見的,而靜態局部變量只對定義自己的函數體始終可見。
- 下面是局部靜態變量為什么值不會變的例子:
#include <iostream>
using namespace std;
void sum(int a, int b){
static int add = 0;
add = a + b;
cout << add << endl;
}
int main(){
sum(1, 2);
sum(2, 3);
}
輸出結果為:
3
5
- 從這個例子可以看出主函數中第一個sum函數的調用使local static add的值變為了3,但當第一個sum函數體結束后,add並未被銷毀且值變為了初始化時的值,於是第二個sum函數得到了正確的解。
三.靜態函數(在函數返回類型前加static關鍵字)
- 函數的定義與聲明在默認情況下為extern,而靜態函數只在聲明它的文件中可見,不可被其他文件使用。—只可在本cpp內使用,不會同其他cpp的同名函數引起沖突。
- warning:不要在頭文件(.h)中聲明static函數,不要在(.cpp)中聲明非static函數。如果在多個cpp復用該函數,就把它的聲明提到頭文件(.h)中,否則代碼復用需要在各個cpp內部聲明加static關鍵字,且編寫大量重復代碼。
- 但由此也帶來一個優點就是:其他文件中可以定義相同名字的函數,不會發生沖突。
四.類中的靜態成員變量
- 優點:靜態成員可以實現多個對象之間的數據共享,並且還不會破壞隱藏的原則,保證了安全性。公共靜態數據成員可被類的外部訪問,保護或私有靜態數據成員只可被類的內部訪問。
- 靜態成員是類的所有對象中共享的成員,而不是某個對象的成員。對多個對象來說,靜態數據成員只存儲一處,供所有對象共用。
五.類的靜態成員函數
- 一個靜態成員函數不與任何對象相聯系,故不能對非靜態成員進行默認訪問,只可以引用類中聲明的靜態成員(important)。但如果靜態成員函數要引用非靜態成員,可通過對象來引用。
- 舉例:
#include <iostream>
class Date{
public:
Date() = default;
Date(int month, int day, int year) {
this->month = month;
this->day = day;
this->year = year;
}
static display(Date date){
std::cout << date.month << " " << date.day << " " << date.year << std::endl;
}
private:
int month{5};
int day{21};
int year{2002};
};
int main(){
Date d;
Date::display(d);
}
- 最尋常的調用靜態函數的格式:
<className>::<static function name>(參數名);
- 靜態成員函數與非靜態成員函數的根本區別是什么?他們的根本區別就是靜態成員函數沒有this指針,而非靜態成員函數有一個指向當前對象的指針this。
- 如果類的成員函數想作為回調函數來使用,如創建線程等,一般只能將它定義為靜態成員函數才行。
六.友元函數(tips:這雖然不是這篇文章的主題,但已經說到了成員函數,就想把友元也說一下記錄一下)
- 為什么需要友元?
有時,普通函數需要直接訪問一個類的保護或者私有數據成員(主要為了提高效率和方便編程),若無友元機制,只能將類的數據成員聲明為public,這嚴重違反了封裝性即安全性,任何函數均可以無拘無束的訪問它。 - 優點:<1>避免頻繁調用成員函數,提高效率。
<2>方便重載操作符的使用。 - 友元函數可以聲明在類的任何位置,但也僅僅只能聲明它的函數原型(函數返回值前加friend),定義則在類的外部,一般與成員函數的定義在一起,因為類重用時,友元一起提供。
- 一個類的成員函數可以是另一個類的友元;整個類也可以是另一個類的友元,稱為友類。友類中的每個成員函數都可訪問另一個類中的保護數據成員(protected)和私有數據成員(private)