函數內部聲明,生命週期贯穿整個程序,初始化僅一次(首次經過定義語句時)。
size_t count_calls() {
static size_t ctr = 0; // 僅初始化一次
return ++ctr;
}
int main() {
for(size_t i=0; i!=10; ++i)
cout << count_calls() << endl; // 輸出 1 2 3 ... 10
}
特性:保持跨調用狀態,線程不安全(C++11起局部static初始化線程安全)。
class Account {
public:
void applyInterest() { amount += amount * interestRate; }
static double rate() { return interestRate; }
static void rate(double newRate) { interestRate = newRate; }
private:
static double interestRate; // 聲明
double amount;
};
// 類外定義(必須,且僅一次)
double Account::interestRate = 0.05;
// 使用
Account::rate(0.07); // 類名調用
Account ac; ac.rate(); // 對象調用
Account* p = ∾ p->rate(); // 指針調用
**唯一可在類內初始化的static成員**(需常量表達式):
class Account {
static const int period = 30; // 類內初始化合法
static double daily_tbl[period]; // 可用作數組維度
// ...
};
// 若需取地址或綁定引用,仍需類外定義:
const int Account::period;
class Base { static int n; };
class Derived : public Base { };
// Base::n 和 Derived::n 為同一實體
// sizeof(Base) 不包含 n
// 舊式(C風格,不推薦)
static int file_global; // 僅本文件可見
// 現代C++(推薦)
namespace {
int file_global; // 同樣文件級隔離
struct LocalStruct { }; // 可用於類/結構體(static不能修飾類)
}
| 類型 | 生命週期 | 作用域 | 初始化位置 | 訪問方式 |
|---|---|---|---|---|
| static局部變量 | 程序結束 | 函數內 | 定義處(首次經過) | 直接名字 |
| static數據成員 | 程序結束 | 類作用域 | 類外(const整型可類內) | 類名::/對象./指針-> |
| static成員函數 | 無狀態 | 類作用域 | 類內/類外定義 | 類名::/對象./指針-> |