C++ static 關鍵字在類內部有兩種含義:**靜態資料成員**(類級別共享變數)與**靜態函數成員**(類級別共享函數)。本文系統總結其語法、初始化規則、存取方式、常見陷阱與最佳實務。
class Point {
public:
Point(int x=0, int y=0) : x_(x), y_(y) { ++count_; }
~Point() { --count_; }
static int get_count() { return count_; } // 靜態函數存取
private:
int x_, y_;
static int count_; // 宣告(非定義)
};
// 類外定義(必須!分配儲存空間)
int Point::count_ = 0;
sizeof(Point) 不含 count_)count_Point::count_(推薦)或 obj.count_(語法糖,編譯器轉為類名存取)undefined reference to Point::count_inline static int count_ = 0; C++17)++count_ 非原子 → 需 std::atomic 或鎖保護
class Point {
public:
static void print_count() {
// std::cout << this->x_; // 錯誤:無 this 指標
std::cout << count_; // 僅能存取 static 成員
}
private:
static int count_;
};
this 指標:無法存取非靜態成員virtual static 非法const/volatile:無物件語境Point::print_count()(推薦)或 obj.print_count()static Point* create(...)static Singleton& instance()static int get_count()static int compare(const Point&, const Point&)inline static 現代化寫法
class Point {
public:
Point(int x=0, int y=0) : x_(x), y_(y) { ++count_; }
~Point() { --count_; }
static int get_count() { return count_; }
private:
int x_, y_;
inline static int count_ = 0; // 宣告即定義,無需類外定義
};
優勢:Header-only 庫友善、避免 ODR 違規、支援模板類別靜態成員。
| 維度 | static 成員 | 全域變數 |
|---|---|---|
| 封裝性 | 受 private/protected 控制 | 全域可見 |
| 命名空間 | 類作用域 Class::member | 全域/命名空間 |
| 初始化順序 | 跨 TU 有序(C++17 保證) | 跨 TU 無序(隱患) |
| 模板支援 | 每個實例化類別獨立一份 | 單一實體 |
inline static (C++17) 簡化定義正確使用 static 成員,能優雅實現類級別共享狀態與工廠模式,是 C++ 物件模型的重要組成部分。